为什么NSNumber错了算一个零售额?

时间:2011-12-01 10:46:22

标签: objective-c

这是零售额代码。

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{

    @autoreleasepool {

        NSNumber *number = [[NSNumber alloc]initWithInt:10];
        NSMutableArray *array = [[NSMutableArray alloc]initWithCapacity:0];

        NSLog(@"retain count : %d",[number retainCount]);

        [array addObject:number];
        NSLog(@"retain count : %d",[number retainCount]);

        [number release];
        NSLog(@"retain count : %d",[number retainCount]);

        [number release];
        NSLog(@"retain count : %d",[number retainCount]);

        [number release];
        NSLog(@"retain count : %d",[number retainCount]);
    }
    return 0;
}

我的预期答案是

retain count : 1
retain count : 2
retain count : 1
retain count : 0
and then error

但实际运行结果如下。

[Switching to process 6363 thread 0x0]
2011-12-01 19:39:53.843 nsnumber[6363:707] retain count : -1
2011-12-01 19:39:53.846 nsnumber[6363:707] retain count : -1
2011-12-01 19:39:53.847 nsnumber[6363:707] retain count : -1
2011-12-01 19:39:53.847 nsnumber[6363:707] retain count : -1
2011-12-01 19:39:53.848 nsnumber[6363:707] retain count : -1

我无法理解这个结果。

为什么结果会来?

4 个答案:

答案 0 :(得分:3)

不要相信保留计数的值。特别是当你使用ARC时!按照规则。就是这样。

答案 1 :(得分:3)

NSNumber返回某些数字的单例实例(我相信整数1到12或其他东西)。

你不应该依赖retainCount的价值。在整个代码或框架代码中可能会发生任何可能改变保留计数的事情。

答案 2 :(得分:1)

关于retainCount

  

此方法在调试内存管理方面通常没有任何价值   的问题。因为任何数量的框架对象都可能保留了一个   对象,以便同时保持对它的引用   自动释放池可能持有任意数量的延期版本   对象,你不太可能从中获取有用的信息   这种方法。

另见

http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/retainCount

When to use -retainCount?

答案 3 :(得分:1)

retainCount的返回类型为NSUInteger;这是一个无符号整数。 string format specifier %d用于签名的整数。

Cocoa使用NSUIntegerMax来表示不朽对象的保留计数 - 永远不会被释放的对象。出于性能原因,它会缓存并重用表示小整数的NSNumber个对象 - 您创建的NSNumber显然是其中之一,并且是不朽的。

当您将最大无符号整数值解释为已签名时(在two's complement arithmetic下),它似乎为-1。

要查看“true”值,您应该使用说明符%lu,如我上面链接的图表所示。

但是,您通常shouldn't rely on retainCount to give you any useful information。这is documented

  

因为任意数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以你不太可能获得有用的这种方法的信息。

beryllium already noted