2

我在 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在不同的时间。有规律吗?我发现我也可以这样做[n1 retain][n1 release]它会相应地增加和减少保留计数。

4

2 回答 2

4

我不知道。

StackOverflow 上的任何人都没有。

为什么?

因为只有苹果的工程师知道。Foundation 只是在它的接口上很简单——底层的实现是一团糟。它与 Objective-C 运行时混合在一起,针对许多可能或可能的情况进行了艰苦的优化,如果文档中提到某些东西是不可依赖的,那就要认真对待。

- retainCount是其中之一。它不能获取类的特定实例的实际引用计数——它的绝对值是没有意义的。在这种方法的情况下,只有相对变化才有意义。使用自动释放池和自动引用计数(尽管在这里不适用)增加了另一个层次的歧义。

这就是为什么。

哦,是的,请查看 http://whentouseretaincount.com

于 2012-09-14T04:50:00.117 回答
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,因为retain count被 的使用加了1 @1,再一次被数组retain,所以一共是600次)。它表明@1任何地方的任何使用都会增加保留计数,并且这个 NSNumber 对象可能被放置在自动释放池中相同的次数。

于 2012-09-14T05:42:26.563 回答