我正在努力完成这个难题.
__strong是所有Objective-C可保留对象指针的默认值,如NSObject,NSString等.这是一个强大的参考.ARC -release在范围的末尾与a平衡.
__unsafe_unretained等于旧的方式.它用于弱指针而不保留可保留对象.
__weak就像__unsafe_unretained不同之处在于它是一个自动归零弱引用这意味着该指针将零一旦引用的对象被释放被设置为.这消除了悬空指针和EXC_BAD_ACCESS错误的危险.
但到底有什么__autoreleasing好处呢?我很难找到关于何时需要使用此限定符的实际示例.我相信它只适用于期望指针指针的函数和方法,例如:
- (BOOL)save:(NSError**);
Run Code Online (Sandbox Code Playgroud)
要么
NSError *error = nil;
[database save:&error];
Run Code Online (Sandbox Code Playgroud)
在ARC下必须以这种方式声明:
- (BOOL)save:(NSError* __autoreleasing *);
Run Code Online (Sandbox Code Playgroud)
但这太模糊了,我想完全理解为什么.我找到的代码片段将__autoreleasing放在两颗星之间,这对我来说很奇怪.类型是NSError**(一个指针指向NSError),那么为什么要放在__autoreleasing星星之间而不是简单地放在前面NSError**呢?
此外,可能还有其他必须依赖的情况__autoreleasing.
有人可以__autoreleasing在下面的示例代码块中向我解释一下目的吗?
- (void)execute:(NSError * __autoreleasing *)error {
// do stuff, possibly assigning error if something went wrong
}
Run Code Online (Sandbox Code Playgroud)
我删除了__autoreleasing所有东西似乎仍然编译/运行正常.我开始使用obj-c后ARC,所以我从来没有真正学过/理解所有那些双下划线的东西.我已阅读ARC过渡指南,但我不完全了解他们的NSError示例.
根据过渡到ARC发行说明:
__autoreleasing用于表示通过引用(id*)传递的参数,并在返回时自动释放.
例如:
-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
但与上述相比,上述优点有哪些:
-(BOOL)performOperationWithError:(NSError * __strong *)error;
更新:
几个答案是指临时VAR招编译器处理为var和参数之间的不匹配的优势的__autoreleasing.我不明白为什么编译器不能为__strong参数做同样的技巧.我的意思是,对于__weakvar和__strong参数,编译器可以类似地执行此操作:
NSError * __weak error;
NSError * __strong tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
// Report the error.
}
Run Code Online (Sandbox Code Playgroud)
编译器知道-(BOOL)performOperationWithError:(NSError * __strong *)error;返回一个强引用(+1),所以它像任何new-family方法一样处理它.由于tmp生活在相同的范围内error,编译器可以合理地保持它活着,只要error这样__weak引用(error)现在由__strongreference(tmp)支持,并且在范围结束之前不会无效.
以下代码取自"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*?