0
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);
4

2 回答 2

13

你的问题是你期望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

这一切都在内存管理编程指南中非常清楚地列出。

于 2011-04-21T04:55:38.370 回答
1
  1. 创建一个您拥有的新可变字符串 ms (如果您“分配”它您拥有它*),因此它以保留计数 1 开始(并且不是“自动释放”)
  2. ms2 也是如此(如果您通过“复制”创建它,您就拥有它*)
  3. ms2 被 NSValue 的 sw 包裹,但 sw 不想保留 ms2 (valueWithNonRetainedObject),因此 ms2 的保留计数不会增加
  4. ms 和 sw 被添加到可变数组 a。数组总是保留它们的元素,因此 ms 和 sw 的保留计数增加一 - 但不是 ms2 的保留计数,因为它不是数组的元素(而是 NSValue sw 的元素)

*) 见内存管理规则

于 2011-04-21T05:44:30.357 回答