an0*_*an0 7 objective-c automatic-ref-counting
根据过渡到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)支持,并且在范围结束之前不会无效.
在这种情况下隐式地将__weak对象转换为对象__strong会改变程序的语义,这是编译器永远不应该做的事情.
我们来举个例子吧
NSError *error;
BOOL success = [myObject performOperationWithError:&error];
if (!success) {
// Report the error
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下error,ARC将自动推断出局部变量__strong.
同时error论证
-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
Run Code Online (Sandbox Code Playgroud)
是类型的NSError * __autoreleasing *.
请注意,在任何情况下,ARC都会将reference(id *)传递的参数推断为类型id __autoreleasing *,因此上述签名相当于
-(BOOL)performOperationWithError:(NSError **)error;
Run Code Online (Sandbox Code Playgroud)
在ARC下.
因此我们有一个不匹配,因为我们将一个带__strong注释的变量传递给一个期望__autoreleasing参数的方法.
在我们的示例中,编译器将通过创建局部__autoreleasing tmp变量来解决这种不匹配问题 .
代码变成了
NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL success = [myObject performOperationWithError:&tmp];
error = tmp;
if (!success) {
// Report the error.
}
Run Code Online (Sandbox Code Playgroud)
我们现在假装我们可以改变签名performOperationWithError:.
如果我们想避免使用tmp变量的"编译器技巧" ,我们可以将我们的签名声明为
-(BOOL)performOperationWithError:(NSError * __strong *)error;
Run Code Online (Sandbox Code Playgroud)
我们有一个__strong变量,我们现在将它传递给一个期望__strong参数的方法,所以我们只是消除了不匹配.
__strong参数?一个原因是声明参数__autoreleasing将使方法甚至接受__weak引用.
在当前的例子中它没有多大意义,但是可能存在这样的情况:我们希望__weak通过引用传递变量并声明__autoreleasing(或让ARC推断它)将允许我们这样做.
ARC将应用上面看到的相同技巧,创建一个__autoreleasing tmp变量.
到目前为止提出的机制是以pass-by-writeback的名义进行的.
这种机制的设计一起工作__autoreleasing,__strong和__weak变量,从而使程序员可以安全地依赖于编译器中的类型推断,而不是太在意周围的注释变量.
id __strong *在某些情况下声明参数可能有意义,但通常它可能会导致编译器生成意外错误.
我的建议是:"让编译器发挥他的魔力,你会很好"
我不明白为什么编译器不能为
__strong参数做同样的技巧.
告诉编译器以一种__autoreleasing方式处理一个__strong或一个__weak变量的管理,因为它基本上意味着:"请,编译器,自动做正确的事情".
这就是为什么上面看到的技巧可以毫无问题地运作.
另一方面,如果你声明一个变量,因为__weak你可能有充分的理由这样做,而你想要的最后一件事就是在你明确指出的时候隐含地保留它.这将从根本上改变你编写的代码片段的语义,因此编译器不会这样做(感谢上帝!).
换一种说法
__weak - > __autoreleasing 好
__strong - > __autoreleasing 好
__weak < - > __strong 错了!
| 归档时间: |
|
| 查看次数: |
753 次 |
| 最近记录: |