有人能解释一下这个保留计数代码中发生了什么吗?

时间:2011-04-21 04:44:52

标签: objective-c retaincount

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

2 个答案:

答案 0 :(得分:13)

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

它不是,你应该忘记retainCount EXISTS

但这是发生的事情:

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”)。如果您满足这四个条件之一(并且文档/方法声明没有另外说明),那么您“拥有”该对象并且必须通过在该对象上调用releaseautorelease来放弃该所有权

这一点在Memory Management Programming Guide中非常明确。

答案 1 :(得分:1)

  1. 创建一个新的可变字符串ms,你拥有它(如果你“分配”它你拥有它*)因此它以一个保留计数开始(并且不是“自动释放”)
  2. 同样适用于ms2(如果你通过“copy”创建它,你拥有它*)
  3. ms2由sw的NSValue包装,但sw不想保留ms2(valueWithNonRetainedObject),因此ms2的保留计数不会增加
  4. ms和sw被添加到可变数组a中。数组总是保留其元素,因此ms和sw的保留计数增加1 - 但不是ms2的保留计数,因为它不是数组的元素(而是NSValue sw)
  5. *)请参阅the memory management rules