Objective c 为什么NSNumber会有如此奇怪的重新计数?
在上面的代码中,为什么n的retainCount的值设置为2?在代码的第二行,我没有使用retain来增加retainCount的数量Objective c 为什么NSNumber会有如此奇怪的重新计数?,objective-c,memory-management,Objective C,Memory Management,在上面的代码中,为什么n的retainCount的值设置为2?在代码的第二行,我没有使用retain来增加retainCount的数量 我发现了一个奇怪的情况。实际上,重新计数取决于初始编号: NSNumber* n = [[NSNumber alloc] initWithInt:100]; NSNumber* n1 = n; 我想你还有别的事 NSNumber *n = [[NSNumber alloc] initWithInt:100]; // n has a retainCount
我发现了一个奇怪的情况。实际上,重新计数取决于初始编号:
NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSNumber* n1 = n;
我想你还有别的事
NSNumber *n = [[NSNumber alloc] initWithInt:100];
// n has a retainCount of 1
NSNumber *n2 = [[NSNumber alloc] initWithInt:11];
// n has a retainCount of 2
结果是1我想你还有别的事
NSNumber *n = [[NSNumber alloc] initWithInt:100];
// n has a retainCount of 1
NSNumber *n2 = [[NSNumber alloc] initWithInt:11];
// n has a retainCount of 2
结果是1停止。停下来永远不要查看对象的
retainCount
。曾经它不应该是API和可用的。你在要求痛苦
有太多的事情发生了,
retainCount
没有意义。停止。停下来永远不要查看对象的retainCount
。曾经它不应该是API和可用的。你在要求痛苦
retainCount
的意义太多了。基于此链接,可能在常见NSNumber的封面下进行了一些优化(这可能不会在所有实现中发生,因此@dizy的retainCount为1的可能原因)
基本上,因为NSNumbers是不可变的,所以底层代码可以免费为您提供同一个数字的第二个副本,这可以解释为什么retain计数为2
n和n1的地址是什么?我怀疑他们是一样的
NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSNumber* n1 = n;
NSLog(@"n = %i",[n retainCount]);
根据你的更新,我给你的链接几乎肯定是问题所在。有人运行了一个测试,发现从0到12的NSNUMBER将为您提供已经创建的NSNUMBER的副本(实际上,它们可能是在用户请求之前由框架创建的)。其他12岁以上的人似乎给出了1的保留计数。引述:
从我所能做的一点检查来看,对于[0-12]范围内的值,似乎您将获得整数NSNumbers的“共享”版本。任何大于12的值都将获得唯一实例,即使值相等。为什么是十二?没有线索。我甚至不知道这是一个硬性数字还是间接数字
尝试使用11、12和13-我想你会发现13是第一个给你一个非共享NSNumber的。基于这个链接,可能在普通NSNumber的封面下进行了一些优化(这可能不会发生在所有实现中,因此@dizy的重新计数可能是1)
基本上,因为NSNumbers是不可变的,所以底层代码可以免费为您提供同一个数字的第二个副本,这可以解释为什么retain计数为2
n和n1的地址是什么?我怀疑他们是一样的
NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSNumber* n1 = n;
NSLog(@"n = %i",[n retainCount]);
根据你的更新,我给你的链接几乎肯定是问题所在。有人运行了一个测试,发现从0到12的NSNUMBER将为您提供已经创建的NSNUMBER的副本(实际上,它们可能是在用户请求之前由框架创建的)。其他12岁以上的人似乎给出了1的保留计数。引述:
从我所能做的一点检查来看,对于[0-12]范围内的值,似乎您将获得整数NSNumbers的“共享”版本。任何大于12的值都将获得唯一实例,即使值相等。为什么是十二?没有线索。我甚至不知道这是一个硬性数字还是间接数字
尝试使用11、12和13-我想您会发现13是第一个提供非共享NSNumber的。保留计数是一个实现细节。有时,它们在调试中可能会很有用,但一般来说,您不应该关心它们。你应该关心的是,你在遵循规则 举个例子说明为什么查看保留计数是不可靠的,这是一个完全合法的类,它遵守API合同,并且在所有情况下都能正确操作:
NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSLog(@"Count of n : %i",[n retainCount]);
NSNumber* n1 = n;
NSLog(@"Count of n : %i",[n retainCount]);
NSLog(@"Count of n1: %i",[n1 retainCount]);
NSLog(@"Address of n : %p", n);
NSLog(@"Address of n1: %p", n1);
@实现CrazyClass
-(id)保留{
for(int i=0;iRetain counts是一个实现细节。它们有时在调试中可能会很有用,但一般来说,您不应该关心它们。您应该关心的是,您正在遵循以下步骤
举个例子说明为什么查看保留计数是不可靠的,这是一个完全合法的类,它遵守API合同,并且在所有情况下都能正确操作:
NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSLog(@"Count of n : %i",[n retainCount]);
NSNumber* n1 = n;
NSLog(@"Count of n : %i",[n retainCount]);
NSLog(@"Count of n1: %i",[n1 retainCount]);
NSLog(@"Address of n : %p", n);
NSLog(@"Address of n1: %p", n1);
@实现CrazyClass
-(id)保留{
对于(int i=0;i,您应该绝不依赖对象的重新计数。您应该仅将其用作调试辅助,绝不用于正常的控制流
为什么?因为它没有考虑到retain
s。如果一个对象是retain
ed,并且不连续地autorelease
d,那么它的retainCount
将增加,但就您而言,它的实际保留计数没有改变。获得对象的实际保留计数的唯一方法是还计算纽约时报,它被添加到自动释放池链中的任何自动释放池中,试图这样做是自找麻烦
在这种情况下,retainCount
是2,因为在alloc
或initWithInt:
中的某个地方,对象被retain
ed和autorelease
d。但是您不需要知道或关心这一点,这是一个实现细节。永远不要依赖retainconun对象的t
。您应该仅将其用作调试辅助工具,而不是用于正常的控制流
为什么?因为它没有考虑到retain
s。如果一个对象是retain
ed,并且不连续地autorelease
d,那么它的retainCount
将增加,但就您而言,它的实际保留计数没有改变。获得对象的实际保留计数的唯一方法是还计算纽约时报,它被添加到自动释放池链中的任何自动释放池中,试图这样做是自找麻烦
在这种情况下,retainCount
i