ios - 为什么 ARC 完全使用自动释放?

标签 ios automatic-ref-counting

我在 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/

相关文章:

ios - UIlabel 在运行时给出了错误的浮点值

ios - 如何使用 Gluon 应用程序打开/发送 URL 到 iOS 上的另一个应用程序?

ios - ABAddressBook 和 CFRelease 的奇怪之处

objective-c - 奇怪的 ARC 问题没有在 UIView 子类中释放 ivar

objective-c - forwardInvocation : + getArgument:atIndex methods 中出现奇怪的 "zombie"

iOS:在 iPad 模态视图中获取键盘点的顶部?

iphone - 架构 armv7s 的 undefined symbol :

iphone - iOS 确定以编程方式创建的按钮

objective-c - 为什么 ARC 迁移器说 NSInvocation 的 -setArgument : is not safe unless the argument is __unsafe_unretained?

objective-c - CoreData 如何使用 Search 和 ARC 过滤 NSFetchedResultsController