【发布时间】:2012-11-05 05:16:12
【问题描述】:
特别是,这种代码是否总是按预期工作(其中 MyResourceGuard 是一个在其 init 方法中锁定独占资源并在其 dealloc 方法中释放锁定的对象):
NSLog(@"About to capture some exclusive resource.");
{
MyResourceGuard* guard = [MyResourceGuard new];
// Do something with the exclusive resource here.
}
// guard is out of scope, therefore its dealloc should have
// been called right away and the resource should already
// be free again at this point.
我在书籍和博客中读过与例如Java 垃圾回收,ARC 会在引用计数减少到零时立即销毁对象(而不是在它自己方便的时候),但我没有在 Apple 的任何官方文档中读到这一点。如果这是真的,为什么我们需要 ARC 引入的新的 @autoreleasepool 关键字?
在调试过程中,我总是看到对象立即被释放,除非在 try-catch-block 中引发异常,在这种情况下,实际上 从未 调用了 dealloc(这是Mac 错误,或者只是这些可怕的 Objective C 怪事之一?)。
【问题讨论】:
-
“如果那是真的,我们为什么需要 ARC 引入的新的 @autoreleasepool 关键字?”因为仍然需要自动释放(因为您需要能够传递刚刚创建的对象,例如访问器),并且编译器需要明智地使用自动释放语义。
-
...在 try-catch-block 中引发了一个异常,在这种情况下实际上从未调用过 dealloc -- ARC + ObjC 不会在这里救你。该对象会泄漏(除非 ARC 认为自动释放池是一个更好的地方)。 ARC + ObjC 在展开时不会生成清理代码。 ARC + ObjC++ 会做一些清理工作(不是全部)。最好避免 ObjC 中的异常 :)
-
请注意,除了记录应用程序中的致命崩溃状态外,您不应将 try-catch 块用于任何事情;异常不应被视为可恢复的。
-
@Jesper:在 ARC 下,由于额外的外部引用,将对象传递出访问器会增加引用计数。一旦该外部引用不再存在,该对象将被释放;与自动释放池无关。
-
@AndreasZollmann:假设两端都是 ARC,是的,感谢
objc_retainAutoreleaseReturnValue/objc_retainAutoreleasedReturnValue相互作用。如果任何目的是手动保留/释放,你就不能做出这样的假设,所以自动释放是必要的。
标签: objective-c ios macos xcode4 automatic-ref-counting