Objective c 为什么@1的保留计数等于7、8或10?

Objective c 为什么@1的保留计数等于7、8或10?,objective-c,memory-management,retaincount,Objective C,Memory Management,Retaincount,我在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"

我在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(可能意味着最大无符号整数),但是
@1
的保留计数在不同的时间实际上是7、8和10。有规则吗?我发现我也可以做
[n1 retain]
[n1 release]
,它会相应地增加和减少保留计数。

我不知道

StackOverflow上的任何人也没有

为什么?

因为只有苹果的工程师知道这一点。基金会只在其接口中简单,底层实现是一团糟。它与Objective-C运行时混合在一起,针对许多可能或可能的情况进行了艰苦的优化,如果文档中提到某件事不值得信赖,那么就要认真对待

-retainCount
就是其中之一。它不是用来获取类的特定实例的实际引用计数的——它的绝对值是没有意义的。在这种方法中,只有相对变化才有意义。自动释放池和自动引用计数的使用(尽管此处不适用)增加了另一个模糊级别

这就是为什么

哦,是的,一定要退房,我不知道

StackOverflow上的任何人也没有

为什么?

因为只有苹果的工程师知道这一点。基金会只在其接口中简单,底层实现是一团糟。它与Objective-C运行时混合在一起,针对许多可能或可能的情况进行了艰苦的优化,如果文档中提到某件事不值得信赖,那么就要认真对待

-retainCount
就是其中之一。它不是用来获取类的特定实例的实际引用计数的——它的绝对值是没有意义的。在这种方法中,只有相对变化才有意义。自动释放池和自动引用计数的使用(尽管此处不适用)增加了另一个模糊级别

这就是为什么


哦,是的,请检查

我认为这说明了原因:每次遇到
@1
时,它都类似于
[[NSNumber alloc]initWithInt:1]autorelease]
,而且它似乎返回相同的对象。因此,当执行以下操作时:

NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:@1];
}
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
} 
NSMutableArray*arr=[[NSMutableArray alloc]init];
对于(int i=0;i<300;i++){
[arr addObject:@1];
}
保留计数实际上变为610。如果执行以下操作,则情况相同:

NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:@1];
}
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
} 
NSMutableArray*arr=[[NSMutableArray alloc]init];
对于(int i=0;i<300;i++){
[arr addObject:[[NSNumber alloc]initWithInt:1]自动释放]];
} 

更新:它是610,因为使用
@1
,保留计数增加了1,而另一次它被数组保留,所以它是总数的600倍)。它表明,在任何地方使用
@1
都会增加保留计数,并且这个NSNumber对象可能被放置在自动释放池中的次数相同。

我认为这说明了原因:每次遇到
@1
时,它都类似于
[[NSNumber alloc]initWithInt:1]自动释放]
,它似乎返回相同的对象。因此,当执行以下操作时:

NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:@1];
}
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
} 
NSMutableArray*arr=[[NSMutableArray alloc]init];
对于(int i=0;i<300;i++){
[arr addObject:@1];
}
保留计数实际上变为610。如果执行以下操作,则情况相同:

NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:@1];
}
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
    [arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
} 
NSMutableArray*arr=[[NSMutableArray alloc]init];
对于(int i=0;i<300;i++){
[arr addObject:[[NSNumber alloc]initWithInt:1]自动释放]];
} 


更新:它是610,因为使用
@1
,保留计数增加了1,而另一次它被数组保留,所以它是总数的600倍)。这表明在任何地方使用
@1
都会增加保留计数,并且此NSNumber对象可能会以相同的次数放置在自动释放池中。

不要使用保留计数。例如,请检查此处或使用搜索!我并不是说我使用retainCount进行编程。我在这里使用的实验和验证的数字应该是什么is@Jeremy第一,这不是否决正确答案的理由,第二,你不能使用retainCount,即使是这样。@JeremyL只是为了强调一点,H2CO3所说的很重要,你不能使用retainCount来验证数字是否正确。原因很简单:你不(也不可能)知道它应该是什么。不要使用retainCount。例如,请检查此处或使用搜索!我并不是说我使用retainCount进行编程。我在这里使用的实验和验证的数字应该是什么is@Jeremy第一,这不是否决正确答案的理由,第二,你不能使用retainCount,即使是这样。@JeremyL只是为了强调一点,H2CO3所说的很重要,你不能使用retainCount来验证数字是否正确。原因很简单:你不(也不可能)知道它应该是什么。+1,别忘了它带来的一个新的无意义水平ARC@Carl谢谢是的,这也是一个合理的理由,以及自动释放池-我更新了我的答案。+1-不应该阅读并根据保留计数做出决定。使用retain and release遵循内存规则,并依靠它按照规则进行操作。因此,你的答案是,Stackoverflow上的每个用户都过来查看,并且没有人知道这个问题。@Jeremy L不,我没有说他们来查看,也不知道。我说除了美联社没有人