5

特别是,这种代码是否总是按预期工作(其中 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 错误,还是这些可怕的目标之一C 怪事?)。

4

2 回答 2

5

不,如您的示例所示,您没有基于确定性范围的 ObjC 对象的破坏。

例如,这个程序可能会导致死锁:

{ MyResourceGuard* guard = [MyResourceGuard new]; }
{ MyResourceGuard* guard = [MyResourceGuard new]; }

如果您需要此功能,您可以做的最好的事情是使用 C++ 类型(SBRM、RAII)——在 Objective-C++ 中也可用(但不适用于 objc 对象)。

它接近了,但你只需要等到引用计数达到零-dealloc才能被调用,这就是保证关闭的原因(通常 != always)。这个问题实际上与您永远不会依赖或使用-retainCount(如果可用)的原因非常相似。示例:自动释放池、异常、对运行时或 ARC 生成代码的更改、编译器优化、使用具有不同代码生成标志的实现可能会导致 objc 对象的生命周期延长超出范围。

更新

clang 网站上 ARC的整个页面都很好地阅读了这个主题——包括细节、保证(和缺乏保证),但特别是:

6.1。精确的生命周期语义

通常,ARC 维护一个不变量,即在 __strong 对象中保存的可保留对象指针将在对象的完整正式生命周期内保留。受此不变量约束的对象具有精确的生命周期语义。

默认情况下,自动存储持续时间的局部变量没有精确的生命周期语义。这样的对象只是简单的强引用,它保存可保留对象指针类型的值,并且这些值仍然完全受制于本地控制下的值的优化。

理由:严格应用这些精确的生命周期语义是禁止的。许多理论上可能会减少对象生命周期的有用优化将变得不可能。从本质上讲,它承诺太多。

可保留对象所有者类型和自动存储持续时间的局部变量可以使用 objc_precise_lifetime 属性进行注释,以指示它应该被视为具有精确生命周期语义的对象。

基本原理:尽管如此,有时能够强制一个对象在精确的时间释放是有用的,即使该对象似乎没有被使用。这可能并不常见,显式请求这些语义的句法权重不会是负担,甚至可能使代码更清晰。

即使您确实使用了该objc_precise_lifetime属性,它也会应用于该强局部变量的引用计数操作——而不是对象的生命周期。

于 2012-11-16T13:28:08.997 回答
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
}
于 2012-11-16T13:27:39.187 回答