2012-07-12 20 views
1

从: In which situations do we need to write the __autoreleasing ownership qualifier under 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?

更确切地说,我知道当我们将指针传递给指针时,我们“应该”使用__autoreleasing但是,如果我们得到的仅仅是一个非常轻微的性能增益,那么有什么意义呢?

回答

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编程的角度来看,第一个版本没有意义。

+0

+1但直到不清楚。所以你说我的方法无论如何都会起作用?所以如果它无论如何起作用,为什么还要用不同的方式来宣称它呢?无论如何,智能编译器也会生成高效的代码。 – 2012-09-21 03:38:56

+0

您的方法可以工作,因为autoreleased临时变量将在运行循环结束时[或之前]自动释放,并且强引用在超出作用域[或大约]时释放,然后该对象将被释放。这里重要的一点是,你正在创建保存函数将使用的*指针,所以你必须给它一个指向正确类型指针的引用。如果save函数返回如下错误:myError = [self save];则_it_将在内部创建指针,所以不需要临时变量。 – Colin 2012-09-21 13:18:48

+0

你确定代码工作?那么使用__autoreleasing的优势只是一个稍微快一点的代码? – 2012-09-22 14:32:53

相关问题