释放不释放对象
Posted
技术标签:
【中文标题】释放不释放对象【英文标题】:Release doesn't dealloc object 【发布时间】:2013-06-19 11:20:04 【问题描述】:我有一个问题现在可能没有任何实际用处,因为 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;
-
如果对象刚刚创建,保留计数应该是 1 而不是 2?
我知道在这种情况下我应该使用自动释放,这样我就可以返回值,并且调用者可以在它被释放之前使用它。我虽然如果我使用保留它会立即释放对象,但下一个 NSLog 显示它仍然存在,并且值成功返回。
我想知道我是否在一个不允许我在函数中释放对象的自动释放池中。
我知道我应该使用 ARC,但我只是想了解这个结果的原因。
【问题讨论】:
据我所知,当retain count达到0时,对象只是被标记为删除,并没有真正被删除。我不是 MRC 的专家,但可能是错误的。 @Fonix:当保留计数达到 0 时,立即释放对象 。但这并不一定意味着内存无效。 - 但在这种情况下,保留计数未达到 0,如我的回答中所述。 【参考方案1】:您永远不应依赖保留计数的特定值(请参阅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
对象。
您拥有使用名称以“alloc”、“new”、“copy”或“mutableCopy”开头的方法创建的对象
如果您使用 retain
取得所有权,则您拥有一个对象。
你的方法的正确版本是
+ (NSNumber *)releaseCorrectly
NSNumber *createdNumber = [[[NSNumber alloc] initWithInteger:5] autorelease];
return createdNumber;
autorelease
平衡了alloc
,但确保对象仍然有效
返回调用方法时。会在当前自动释放时释放
池被破坏,例如当程序控制返回到主事件循环时。
【讨论】:
谢谢!你提供给我的链接真的很有用。以上是关于释放不释放对象的主要内容,如果未能解决你的问题,请参考以下文章
已释放对象的校验和不正确 - 对象在被释放后可能已被修改。我该如何解决?