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 回答
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
- 创建一个您拥有的新可变字符串 ms (如果您“分配”它您拥有它*),因此它以保留计数 1 开始(并且不是“自动释放”)
- ms2 也是如此(如果您通过“复制”创建它,您就拥有它*)
- ms2 被 NSValue 的 sw 包裹,但 sw 不想保留 ms2 (valueWithNonRetainedObject),因此 ms2 的保留计数不会增加
- ms 和 sw 被添加到可变数组 a。数组总是保留它们的元素,因此 ms 和 sw 的保留计数增加一 - 但不是 ms2 的保留计数,因为它不是数组的元素(而是 NSValue sw 的元素)
*) 见内存管理规则
于 2011-04-21T05:44:30.357 回答