【问题标题】:Can anybody explain me what is happening in this retain count code?谁能解释一下这个保留计数代码中发生了什么?
【发布时间】:2011-04-21 04:44:52
【问题描述】:
NSMutableString *ms = [[NSMutableString alloc]init];
[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];
NSMutableString *ms2 = [ms mutableCopy];
NSLog(@"ms retain count:%lu",ms.retainCount);
NSLog(@"ms2 retain count:%lu",ms2.retainCount);
NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
NSMutableArray *a = [NSMutableArray array];
[a addObject:ms];
[a addObject:sw];
NSLog(@"ms retaincount %lu",ms.retainCount);
NSLog(@"ms2 retaincount %lu",ms2.retainCount);

【问题讨论】:

    标签: objective-c retaincount


    【解决方案1】:

    您的问题是您希望 retainCount 有用。

    不存在,您应该忘记retainCount 存在

    但事情是这样的:

    NSMutableString *ms = [[NSMutableString alloc]init];
    

    您已经创建了一个可变字符串。 你拥有它并负责releasing它

    [ms appendFormat:@"element %ld",1];
    [ms appendFormat:@"element %ld",2];
    

    您将一些数据附加到字符串。所有权没有变化。

    NSMutableString *ms2 = [ms mutableCopy];
    

    您创建了字符串的副本。 您拥有该副本并对releasing它负责

    NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
    

    您将指向字符串副本的指针存储在NSValue 中。您不拥有NSValue(因此不必拥有release),并且由于您使用的是NonretainedObject: 变体,因此ms2 对象的所有权不变。

    NSMutableArray *a = [NSMutableArray array];
    

    您创建了一个可变数组。你不拥有它。

    [a addObject:ms];
    

    您将一个对象添加到数组中。 数组现在也拥有对象

    [a addObject:sw];
    

    您将一个对象添加到数组中。 数组现在拥有对象(你仍然不拥有它)

    所以在这段代码的最后,你拥有:

    • ms
    • ms2

    这意味着要使您的代码正确,您还应该:

    [ms release];
    [ms2 release];
    

    编辑:

    你怎么知道你什么时候“拥有”一个对象,什么时候不?很简单:

    • 如果您通过以单词“alloc”或开头的方法检索对象...
    • 如果您通过以“new”开头的方法检索对象或...
    • 如果您通过包含单词“copy”或...的方法检索对象...
    • 如果您明确地“retain”对象

    请记住:New-Alloc-Retain-Copy(“NARC”)。如果您满足这四个条件之一(并且文档/方法声明没有另外说明),那么您“拥有”该对象并且必须通过对该对象调用 release 或 autorelease 来放弃该所有权。

    这一切都在Memory Management Programming Guide 中非常清楚地列出。

    【讨论】:

    • 谢谢 Dave,这里是输出,现在我明白为什么它显示了一些奇怪的输出
    • 这意味着它在输出中是什么意思 2011-04-21 10:35:31.765 retaincountpgm[399:903] *** __NSAutoreleaseNoPool(): NSConcreteValue 类的对象 0x100110580 自动释放,没有适当的池- 只是泄漏 2011-04-21 10:35:31.766 retaincountpgm[399:903] *** __NSAutoreleaseNoPool(): NSCFArray 类的对象 0x100110ce0 自动释放,没有适当的池 - 只是泄漏
    • @toddler 就是它所说的。您可能在 main 中运行此程序,但尚未创建 NSAutoreleasePool。
    • @toddler:创建对象但不是alloc、new 或copy 的方法为您自动释放对象。为此,当前线程上必须有一个自动释放池。内存管理编程指南中更详细地解释了这一点和其他相关内容:developer.apple.com/mac/library/documentation/Cocoa/Conceptual/…
    【解决方案2】:
    1. 创建了一个您拥有的新可变字符串 ms(如果您“分配”它,您就拥有它*),因此它以 1 的保留计数开始(并且不是“自动释放”)
    2. ms2 也是如此(如果您通过“复制”创建它,您就拥有它*)
    3. ms2 被 NSValue 的 sw 包裹,但 sw 不想保留 ms2 (valueWithNonRetainedObject),因此 ms2 的保留计数不会增加
    4. ms 和 sw 被添加到可变数组 a。数组总是保留它们的元素,因此 ms 和 sw 的保留计数加一 - 但不是 ms2 的保留计数,因为它不是数组的元素(而是 NSValue sw 的元素)

    *) 见the memory management rules

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多