2

from: 在什么情况下我们需要在ARC下写__autoreleasing所有权限定符?

  • ( BOOL ) 保存: ( NSError * __autoreleasing * );

然后编译器必须创建一个临时变量,设置为 __autoreleasing。所以:

NSError * e = nil;
[ database save: &error ];

将转化为:

NSError __strong * error = nil;
NSError __autoreleasing * tmpError = error;
[ database save: &tmpError ];
error = tmpError;

好的,现在转换后的代码似乎工作得很好。最后,我预计它会正常工作,尽管效率“很少”(非常少)。那么为什么还要指定自动发布呢?

更准确地说。我知道__autoreleasing当我们将指针传递给指针时我们“应该”使用。但是,如果我们得到的唯一结果只是非常轻微的性能提升,那又有什么意义呢?

4

1 回答 1

1

当变量通过引用传递并在 ARC 程序中分配时,您错过了此代码中实际发生的情况。

在非 ARC 编程中,保存函数如下所示:

- (BOOL)save:(NSError * __autoreleasing *)myError {
  *myError = [[[NSError error] retain] autorelease]
}

在 ARC 编程中,保存函数如下所示:

- (BOOL)save:(NSError * __autoreleasing *)myError {
  *myError = [[NSError alloc] init];
}

不管 ARC 代码是什么样子,两个保存函数都会创建一个已保留并自动释放的错误对象。

这是因为在 ARC 版本中,myError 的指针类型决定了错误对象的内存管理会发生什么。实际上,只要指针是 __autoreleasing 类型,*myError 赋值行就被替换

*myError = [[[NSError error] retain] autorelease]

在运行时。

因此,如果我们能够以某种方式将错误类型的指针传递给保存函数,就会导致保存函数做错事。

由于编译器将在您的示例中创建一个临时变量,因此您的代码可以以任何方式工作,但从 ARC 编程的角度来看,第一个版本没有意义。

于 2012-09-20T21:48:03.607 回答