以下代码取自"iOS 5 Developer's Cookbook",用于说明如何将字符串写入文件.它使用__autoreleasing而没有任何解释.为什么有必要?
NSError __autoreleasing error;
...
if (![myString writeToFile:path atomically:YES error:&error)
{
NSLog(.... error.localizedFailureReason ...);
return;
}
Run Code Online (Sandbox Code Playgroud)
为什么不在不使用__autoreleasing的情况下在堆栈上声明错误?
------编辑-----
附加问题:为什么作者声明NSError而不是NSError*?
当一个变量通过引用传递并在ARC程序中分配时,您将错过此代码中实际发生的情况.以一个函数(BOOL)保存为例:(NSError*__autoreleasing*)错误
在非ARC编程中,保存功能如下所示:
- (BOOL)save:(NSError * __autoreleasing *)myError {
*myError = [[[NSError error] retain] autorelease]
}
Run Code Online (Sandbox Code Playgroud)
在ARC编程中,保存功能如下所示:
- (BOOL)save:(NSError * __autoreleasing *)myError {
*myError = [[NSError alloc] init];
}
Run Code Online (Sandbox Code Playgroud)
尽管ARC代码看起来如此,但两个保存函数都会创建一个已保留并自动释放的错误对象.
这是因为在ARC版本中,myError指针的类型决定了错误对象的内存管理会发生什么.实际上,只要指针是__autoreleasing类型,*myError赋值行就会替换为
*myError = [[[NSError error] retain] autorelease]
Run Code Online (Sandbox Code Playgroud)
在运行时.
因此,如果我们以某种方式能够将错误类型的指针传递给保存函数,例如__strong,则会导致save函数执行错误的操作.
由于编译器将通过创建临时变量来防止这种情况发生,因此代码将以任何一种方式工作,但是从ARC编程角度来看,传入__autoreleasing以外的类型的指针是没有意义的.