我在Xcode 4.4.1上创建了一个空的iOS应用程序,并执行了以下操作:
NSNumber *n1 = @1;
NSNumber *n2 = @2;
NSNumber *n3 = @3;
NSNumber *n100 = @100;
NSString *s = @"haha";
NSArray *a = @[n1, s];
NSDictionary *d = @{ @"ha" : @1, @3 : @"hello" };
NSLog(@"retain count of @1 is %i", [n1 retainCount]);
NSLog(@"retain count of @2 is %i", [n2 retainCount]);
NSLog(@"retain count of @3 is %i", [n3 retainCount]);
NSLog(@"retain count of @100 is %i", [n100 retainCount]);
NSLog(@"retain count of @\"haha\" is %i", [s retainCount]);
NSLog(@"retain count of array literal is %i", [a retainCount]);
NSLog(@"retain count of dictionary literal is %i", [d retainCount]);
结果是:
retain count of @1 is 10
retain count of @2 is 4
retain count of @3 is 5
retain count of @100 is 1
retain count of @"haha" is -1
retain count of array literal is 1
retain count of dictionary literal is 1
所以数组文字和字典文字的保留计数为1,并且据说整个应用程序的运行都存在字符串文字,因此它为-1(可能意味着MAX unsigned int),但保留计数为{ {1}}实际上在不同时间分别为7,8和10。它有规则吗?我发现我也可以执行@1
和[n1 retain]
,并相应地增加和减少保留计数。
答案 0 :(得分:4)
我不知道。
StackOverflow上的任何人都没有。
为什么?
因为只有Apple的工程师才知道它。 Foundation只在其界面中很简单 - 底层实现是 mess 。它与Objective-C运行时混合,在很多可能或可能的情况下进行了优化,如果在文档中提到某些不可依赖的东西,那就应该认真对待。
- retainCount
就是其中之一。它不是为了得到一个类的特定实例的实际引用计数 - 它的绝对值是没有意义的。在此方法的情况下,只有相对更改才有意义。使用自动释放池和自动引用计数(虽然这里不适用)会增加另一种歧义。
这就是原因。
哦,是的,请查看 http://whentouseretaincount.com
答案 1 :(得分:0)
我认为这指出了原因:每次遇到@1
时,它都类似于[[[NSNumber alloc] initWithInt:1] autorelease]
,并且它似乎返回相同的对象。所以当完成以下操作时:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
[arr addObject:@1];
}
保留计数实际上变为610.如果完成以下操作则相同:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
[arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
}
(更新:它是610,因为使用@1
时保留计数增加1,而另一次由数组保留,因此它是600总计)。它建议任何使用@1
任何地方都会增加保留计数,而且这个NSNumber对象可能放在自动释放池中的次数相同。