特别是,这种代码总是按预期工作(其中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关键字?
从调试开始,我总是看到对象dealloc'ed立即,除非在try-catch-block中引发异常,在这种情况下dealloc实际上是从不调用(是一个Mac bug,或者只是其中一个可怕的Objective C奇怪之处?)。
答案 0 :(得分:5)
没有。如示例所示,您没有基于确定性范围的ObjC对象销毁。
例如,此程序可能导致死锁:
{ MyResourceGuard* guard = [MyResourceGuard new]; }
{ MyResourceGuard* guard = [MyResourceGuard new]; }
如果需要此功能,最好的办法是使用C ++类型(SBRM, RAII) - 也可以在Objective-C ++中使用(但不适用于objc对象)。
它接近,但你必须等到参考计数达到零才能调用-dealloc
,这就是保证关闭的原因(通常!=总是)。这个问题实际上非常类似于您永远不会依赖或使用-retainCount
(可用的地方)的原因。示例:自动释放池,异常,对运行时或ARC生成的代码的更改,编译器优化,使用具有不同代码生成标记的实现可能导致objc对象的生命期延长超出范围。
<强>更新强>
whole page on ARC at clang's site是关于这个主题的好读物 - 包括细节,保证(和缺乏保证),但特别是:
6.1。精确的生命周期语义
通常,ARC维护一个可保留对象的不变量 __strong对象中保存的指针将保留为完整的正式 对象的生命周期。受此不变量影响的对象具有精确性 终身语义。
默认情况下,自动存储持续时间的局部变量不具备 精确的生命周期语义。这些对象只是强有力的参考 其中包含可保留对象指针类型的值以及这些值 仍然完全受本地价值优化的影响 控制。
基本原理:严格应用这些精确生命的语义 望而却步。理论上可能有许多有用的优化 减少对象的生命周期将变得不可能。 从本质上讲,它承诺太多。
可保留对象所有者类型和自动存储的局部变量 持续时间可以使用objc_precise_lifetime属性进行注释 表明它应该被认为是一个精确的对象 终身语义。
理由:尽管如此,强迫一个人有时也很有用 要在精确时间释放的对象,即使该对象没有 似乎被使用了。这可能是不常见的 明确请求这些语义的语法权重不会 繁琐,甚至可能使代码更清晰。
即使您使用objc_precise_lifetime
属性,它也会应用于强大的本地变量的引用计数操作 - 而不是对象的生命周期。
答案 1 :(得分:0)
这种代码将始终有效。 (或者至少只要ARC像现在一样工作) ARC中对象生命周期的一个小例子:
{
NSString *a = [[NSString alloc] init]; //object allocation
a = nil; // object is deallocated as it was created in this scope
NSString *b = [NSString string]; //method call which returns an object (always autoreleased)
b = nil; // object is not deallocated as it was not created in this scope and is therefore autorelased
}