我在 ARC 下没有自动释放池的情况下运行这段代码:
- (NSString*) outName {
if (!outName) {
outName = [[NSString alloc] initWithFormat:@"whatever"]; // or stringWithFormat
}
return outName;
}
调试器说它每次都在泄漏 single outName
实例,而没有适当的池。
如果我将代码更改为,这不会发生
- (NSString*) outName {
if (!outName) {
outName = @"whatever";
}
return outName;
}
我做不到(这个例子显然被简化了)。此外,如果我在调用代码中创建一个自动释放池(我想避免这种情况),泄漏消息就会消失。
为什么 ARC 坚持要自动释放这个保存在 strong
属性中的对象?更重要的是,我怎样才能避免这个警告?
最佳答案
这是一个所有权问题。
先说说你自己分配的NSString吧。 当你分配一个对象时,堆中的内存是为该对象保留的(除非你 allocWithZone: 到另一个位置)。保留计数隐式为 1 并且您拥有该对象,即您有责任在完成后释放它。如果您要返回指向该对象的指针,即返回该对象,您并没有完全放弃确保该对象不泄漏的责任。您不能释放它,因为保留计数将变为 0,并且该对象将被释放。你自动释放它,确保在你的运行循环结束时(或更早)对象将被释放并可能被释放。如果返回的对象需要存活更长时间,则调用函数负责保留返回的对象。
如果没有自动释放池,您将会泄漏,因为指定的 autoReleasePool 为 null(记住消息为 null 没问题,这就是为什么这不会崩溃而不仅仅是泄漏)。
带有固定 @"whatever"的示例不会泄漏,因为编译器为该字符串保留了程序内存,并且 -release 对它们没有影响。对于一些低值(value)的 NSNumbers 也是如此。
正如 James 所说,ARC 并没有删除 retain release 和 autorelease 概念。
编辑:如何将 outName 声明为 ivar/属性?
关于ios - 为什么 ARC 完全使用自动释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11191452/