基于此链接在这里,它可能是有一些优化的封面共同NSNumbers去下(这可能不是因此所有的实现发生的可能原因@迪济的retainCount是1).
基本上,因为NSNumbers是不可变的,所以底层代码可以自由地给你一个相同数字的第二个副本,这可以解释为什么保留计数是2.
n和n1的地址是多少?我怀疑他们是一样的.
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);
根据您的更新,我给您的链接几乎肯定是问题.有人进行了测试,发现从0到12的NSNumbers将为您提供已创建的重复项(实际上,即使在用户请求之前,它们也可能由框架创建).12岁以上的人似乎给予保留计数1.引用:
从我能够做的一点点检查,看起来好像你会得到[0-12]范围内的值的"共享"版本的整数NSNumbers.即使值相等,任何大于12的东西都会获得一个唯一的实例.为什么十二?没有线索.我甚至都不知道这是一个难的数字还是间接的.
尝试11,12和13 - 我想你会发现13是第一个给你一个非共享的NSNumber.
基于此链接在这里,它可能是有一些优化的封面共同NSNumbers去下(这可能不是因此所有的实现发生的可能原因@迪济的retainCount是1).
基本上,因为NSNumbers是不可变的,所以底层代码可以自由地给你一个相同数字的第二个副本,这可以解释为什么保留计数是2.
n和n1的地址是多少?我怀疑他们是一样的.
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);
根据您的更新,我给您的链接几乎肯定是问题.有人进行了测试,发现从0到12的NSNumbers将为您提供已创建的重复项(实际上,即使在用户请求之前,它们也可能由框架创建).12岁以上的人似乎给予保留计数1.引用:
从我能够做的一点点检查,看起来好像你会得到[0-12]范围内的值的"共享"版本的整数NSNumbers.即使值相等,任何大于12的东西都会获得一个唯一的实例.为什么十二?没有线索.我甚至都不知道这是一个难的数字还是间接的.
尝试11,12和13 - 我想你会发现13是第一个给你一个非共享的NSNumber.
停止.停下来.永远不要看retainCount
一个物体.永远.它应该永远不是API并且可用.你在寻求痛苦.
retainCount
有意义的事情太多了.
保留计数是一个实现细节.它们在调试时很有用,有时候,但一般情况下你不应该关心它们.您应该关心的是您遵循内存管理规则.
举例说明为什么查看保留计数是不可靠的,这是一个完全合法的类,它遵守API合同并在所有情况下都能正常运行:
@implementation CrazyClass - (id)retain { for(int i=0; i<100; i++) { [super retain]; } } - (void)release { for(int i=0; i<100; i++) { [super release]; } } @end
......但是如果你检查了它的保留计数,你会认为你有一个"问题".
这种精确的情况在实践中并不经常发生,但它说明了为什么查看保留计数对于判断是否有问题毫无用处.通过控件之外的代码将对象保留在幕后.例如,NSNumber有时会缓存实例.对象被自动释放,这不会反映在保留计数中.可能会发生很多会使保留计数混淆的事情.某些类甚至可能无法将保留计数保留在您可以看到它们的位置.
如果您怀疑自己有泄漏,则应该检查用于此目的的实际调试工具,而不是查看保留计数.对于您正在编写的代码,您应该主要关注遵循我上面链接的指南.