1

我对 retainCount 有疑问

NSLog(@"%i", [self.albumReceiver retainCount]);
    self.albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self] autorelease];

    NSLog(@"%i", [self.albumReceiver retainCount]);

第一行的保留计数为 0,但当它到达第三行时为 3。self.albumReceiver 上的属性是保留属性......但据我所知,它应该是 2,而其他后来的保留计数应该去1,因为它是后来自动发布的。

 NSLog(@"%i", [self.albumReceiver retainCount]);
    albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self];

    NSLog(@"%i", [self.albumReceiver retainCount]);

保留计数从 0 开始,在这种情况下,第二个保留计数打印 2....

有人可以给出一些关于保留和释放如何工作的想法......

我以为没有'self'关键字,它会忽略setter调用是吗?但是如果我在第二个例子上放自动释放,我会有错误。

4

4 回答 4

4

首先,保留计数是您不应该过度关注的实现细节。你真的应该只关心所有权。

话虽如此,您所看到的解释如下:

第一行的保留计数为 0

那是因为self.albumReceivernil那个时候。在真实对象上,您永远不会看到保留计数为 0(在 Foundation 的当前实现中)。

当它到达第三行时是 3

通常,您希望保留计数为 2,分配为 +1,分配给保留属性时为 +1。但是,该init:方法可能会导致某些其他对象保留它,属性的设置器也可能会保留它。另一个观察该属性的对象也可能选择保留该对象。简而言之,除非您知道所涉及的所有方法的确切实现,并且您确定没有在 albumReceiver 上使用 KVO,否则您只能说保留计数self拥有它的所有权(NB 所有权不是排他性的,其他事情可能也有所有权)。这就是为什么您不应该过多关注保留计数的原因。

有人可以了解一下这个保留和释放是如何工作的吗

是的。您需要考虑所有权。某些方法会为您提供您拥有的对象。这些是任何以 开头的alloc方法、任何以 开头的方法new、任何以copyormutableCopy和开头的方法-retain。如果您以任何其他方式收到一个物品,您就不拥有它。这包括将它们作为方法的返回结果、方法的 ass 参数或方法的引用参数或全局或静态变量接收。

如果您拥有一个对象,则必须通过释放或自动释放它来放弃所有权,否则它将泄漏。如果您不拥有对象,则不得释放或自动释放它。

我发现最好将上面的“你”理解为“声明对象引用的范围”。

无论如何,我建议您阅读 Apple 的内存管理规则以获得明确的解释,而不是相信这里的答案。如果您查看此答案的原始编辑,您会发现我的规则略有错误,因为自从我上次阅读它们以来它们已经收紧了。

于 2012-05-31T09:36:29.977 回答
2

不要使用retainCount. (对于适合使用它的情况,请参阅此网站。)进一步阅读:bbum 的博客文章之前的 SO 线程一线程二。另请注意,retainCount在最近的 SDK 中已弃用。注意弃用警告是一个好主意,将所有警告变成错误甚至更好。

于 2012-05-31T09:16:09.577 回答
2

在 Objective-C 中关注retainCount对象的 t 通常是一个坏主意,因为通常不可能知道框架的哪些秘密部分需要保留对象。

在您引用将对象添加到自动释放池的位置的情况下,自动释放池可能会保留该对象,直到需要刷新池(在运行循环期间)。这可能解释了为什么autoreleased 对象的保留计数更高。

请注意上一段中“大概”和“可能”这两个词的使用。我不知道这是否真的是 Cocoa/Cocoa Touch 框架内部发生的事情。这是 using 的问题retainCount,您无法随时知道保留计数应该是多少。

如果您retain是对象(或使用包含alloc、或的方法名称创建它),那么您copy就是它。框架对对象也是免费的,当它们准备好时它们就会这样做。当保留计数达到零时,它将被编辑。 mutableCopynewreleaseretainreleasedealloc

更新:查看了 NSObject 和 NSAutoreleasePool 的 GNUStep 源代码后,我上面可能的解释可能不是正在发生的事情。但是,我无法确定,因为我看不到 Apple 对这两个对象的实现。更有理由不信任retainCount或从中得出任何推论。

于 2012-05-31T09:22:22.690 回答
0

在具有手动内存管理的环境中真正存在的唯一规则是

如果您使用alloc, copy, mutableCopy,new

释放它。否则不要。retainCounts 并不能真正用于调试。看这里

于 2012-05-31T09:14:24.963 回答