1

现在我有了一个ClassA : NSObject,然后在 viewcontrollerviewDidLoad中,查看下面的代码:

- (void)viewDidLoad {
    ClassA *a = [[ClassA alloc] init];
    NSLog(@"a retainCount = %d", [a retainCount]);
    ClassA *b = a;
    NSLog(@"a retainCount = %d b retainCount= %d ", [a retainCount],[b retainCount]);
    [a release];
    NSLog(@"a retainCount = %d b retainCount= %d", [a retainCount],[b retainCount]);
    [super viewDidLoad];
}

控制台输出如下所示:

2012-11-02 14:43:35.437 RetainCountTest[1043:207] a retainCount = 1
2012-11-02 14:43:35.439 RetainCountTest[1043:207] a retainCount = 1 b retainCount= 1  
2012-11-02 14:43:35.439 RetainCountTest[1043:207] a retainCount = 1 b retainCount= 1

我不明白,当我打电话时[a release],为什么[a retainCount]== 1?</p>

4

3 回答 3

4

那是因为“ retainCount 没用”。

添加一些上下文:当消息传递一个“死”的对象时,您应该期待未定义的行为。

于 2012-11-02T06:58:24.393 回答
1

当您调用 [a release] 时,您不再持有 a,因此 a 可能会被释放。这里可能就是这种情况,因为它的所有权是共享的。

任何进一步的消息a都具有未定义的返回值:另一个对象可能重用了 a 的内存槽。

所以你打印的返回值本质上是随机的。它可能使您的应用程序崩溃或打印了 1000...

于 2012-11-02T17:37:17.750 回答
1

你永远不应该关注retainCount。它们充其量是令人困惑的,最坏的情况是误导。应该只确保他们正确遵循保留/释放的内存管理规则,而忘记保留计数。

文档..

这种方法在调试内存管理问题时没有任何价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存了任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。

编辑:建议阅读

何时使用 -retainCount?

编辑:看到OP的评论后

来自Cocoa Core 内存管理规则

当您创建或复制一个对象时,其保留计数为 1。此后,其他对象可能表达对您的对象的所有权权益,这会增加其保留计数。对象的所有者也可以放弃他们对它的所有权权益,这会减少保留计数。当保留计数变为零时,对象被释放(销毁)。

如果有人读到这里,他/她可能会想,哦,retainCount 是天赐之物,我只需使用 NSLog 语句就可以看到一个对象的完整分配/保留/释放周期。但它实际上并不是这样工作的。你不能说,你对你创建的对象拥有唯一的所有权。该对象可能被任何其他框架对象保留。释放你只是放弃了你的所有权。只有在所有其他对象删除其引用后,该对象才会被释放。

我不知道为什么它仍然保留在公共 API 中。

于 2012-11-02T06:58:15.473 回答