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

tod*_*e-c 0 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);
Run Code Online (Sandbox Code Playgroud)

Dav*_*ong 13

你的问题是你期望retainCount有用.

它不是,你应该忘记,retainCountEXISTS

但这是发生的事情:

NSMutableString *ms = [[NSMutableString alloc]init];
Run Code Online (Sandbox Code Playgroud)

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

[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];
Run Code Online (Sandbox Code Playgroud)

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

NSMutableString *ms2 = [ms mutableCopy];
Run Code Online (Sandbox Code Playgroud)

您创建该字符串的副本. 您拥有的副本,并负责releasing

NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
Run Code Online (Sandbox Code Playgroud)

您将指针存储到您的字符串副本中NSValue.你没有拥有NSValue(因此也没有release),并且因为你使用的是NonretainedObject:变体,所以ms2对象的所有权不变.

NSMutableArray *a = [NSMutableArray array];
Run Code Online (Sandbox Code Playgroud)

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

[a addObject:ms];
Run Code Online (Sandbox Code Playgroud)

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

[a addObject:sw];
Run Code Online (Sandbox Code Playgroud)

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

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

  • ms
  • ms2

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

[ms release];
[ms2 release];
Run Code Online (Sandbox Code Playgroud)

编辑:

你怎么知道什么时候你"拥有"一个物体而你什么时候不拥有?这很简单:

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

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

" 内存管理编程指南"中非常清楚地说明了这一点.