Objective c 为什么NSNumber会有如此奇怪的重新计数?

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

在上面的代码中,为什么n的retainCount的值设置为2?在代码的第二行,我没有使用retain来增加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