【问题标题】:iOS about retainCountiOS 关于retainCount
【发布时间】:2012-11-02 06:51:09
【问题描述】:

现在我有一个ClassA : NSObject,然后在viewcontroller中viewDidLoad,看下面的代码:

- (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

【问题讨论】:

  • 谢谢! @mttrb,这非常有用。
  • 面试官问retainCount?
  • @bbum 也许这是一个诡计问题,“你永远不应该发送retainCount,尤其是发送给死对象”是正确的答案。
  • 这正是我所希望的。如果面试官表现得很好,那么对并发或自动发布的跟进就会说明问题。 (而且我不一定会批评那些认为retainCount 有用的人——看到候选人在面对使其当前职位无效的信息时改变职位的意愿总是很有趣)。

标签: ios retaincount


【解决方案1】:

那是因为“retainCount is useless”。

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

【讨论】:

  • 我一般不喜欢这么短的答案,但链接的文章解释得很好。
  • 非常感谢,justin,今天面试官给我做了个测试,我回答你用[a release]的时候这个应该是0,现在我用Xcode测试,还是输出1 ,所以我很困惑。请问:retainCount 在哪里变成了0?
  • @Maggie 来自链接文章中的第 5 点:“retainCount 方法永远不能返回 0。”具体来说,在这种情况下,您应该期望的只是未定义的行为。如果你想跟踪引用计数操作,Instruments 会为你记录下来。
【解决方案2】:

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

来自documentation..

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

编辑:建议阅读

When to use -retainCount?

编辑:看到 OP 的评论后

来自Cocoa Core Memory Management rules

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

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

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

【讨论】:

  • 非常感谢,krishnabhadra,今天面试官给我做了一个测试,我回答这个应该在你使用[a release]的时候变成0,现在我在Xcode中测试,它仍然输出1 ,所以我很困惑。
  • 再次感谢@Krishnabhadra,你说得对,我应该遵守内存管理规则。
  • FWIW,在 ARC 中发送 retainCount 消息或 @selector(retainCount) 文字是非法的。
【解决方案3】:

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

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

所以你打印的返回值本质上是随机的。它可能会导致您的应用崩溃或打印 1000...

【讨论】:

    猜你喜欢
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多