我有一个问题可能现在没有任何实际用途,因为ARC非常鼓励,但我正在研究内存管理,而且我有些不太了解。
我有这个方法
+(NSNumber *)releaseTooEarly
{
NSNumber *createdNumber = [[NSNumber alloc] initWithInteger:5];
NSLog(@"retain count before release: %d", createdNumber.retainCount); //Prints 2
[createdNumber release];
NSLog(@"%@", createdNumber); //Prints 5
return createdNumber;
}
我想知道我是否在自动释放池中,不允许我在函数中释放对象。
我知道我应该使用ARC,但我只是想了解这一结果的原因。
答案 0 :(得分:2)
您永远不应该依赖保留计数的特定值(请参阅http://whentouseretaincount.com)。
在这种特殊情况下(如http://www.opensource.apple.com/source/CF/CF-476.19/CFNumber.c所示),NSNumber
缓存创建的对象之间的整数值
(-1)和12,所以调用
[[NSNumber alloc] initWithInteger:5];
反复将始终返回相同的实例。缓存包含对该对象的一个额外引用
这是retainCount == 2
的原因,也解释了为什么对象不是
如果你释放它就会被破坏。
但这只是实施细节!! 。如上所述,您不应使用保留计数。即使一个对象被释放,不必要意味着对象的内存无效,因此访问对象可能显示结果。
请参阅“高级内存管理编程指南”中有关规则的"Basic Memory Management Rules":
release
或autorelease
您拥有的对象。retain
获取所有权,则拥有对象。您的方法的正确版本将是
+ (NSNumber *)releaseCorrectly
{
NSNumber *createdNumber = [[[NSNumber alloc] initWithInteger:5] autorelease];
return createdNumber;
}
autorelease
平衡alloc
,但确保对象仍然有效
当返回调用方法时。它将在当前自动释放时释放
池被破坏,例如程序控制返回主事件循环时。