objective-c – 声明方法参数__autoreleasing有什么好处?

objective-c – 声明方法参数__autoreleasing有什么好处?,第1张

概述按照 Transitioning to ARC Release Notes: __autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return. 例如: – (BOOL)performOperationWithError:(NSError * 按照 Transitioning to ARC Release Notes:

__autoreleasing is used to denote arguments that are passed by reference (ID *) and are autoreleased on return.

例如:

– (BOol)performOperationWithError:(NSError * __autoreleasing *)错误;

但与上述相比,上述优点有哪些:

– (BOol)performOperationWithError:(NSError * __strong *)错误;

更新:

有几个答案引用temp var技巧编译器来处理var和argument之间的不匹配作为__autoreleasing的优点.我不明白为什么编译器不能为__strong参数做同样的技巧.我的意思是,对于__weak var和__strong参数,编译器可以类似地执行此 *** 作:

NSError * __weak error;NSError * __strong tmp = error;BOol OK = [myObject performOperationWithError:&tmp];error = tmp;if (!OK) {    // Report the error.}

编译器知道 – (BOol)performOperationWithError:(NSError * __strong *)错误;返回一个强引用(1),因此它就像任何新的族方法一样处理它.由于tmp与错误存在于相同的范围内,因此编译器可以合理地使其保持活动,只要出现错误,因此__weak引用(错误)现在由__strong引用(tmp)支持,并且在范围结束之前不会无效.

解决方法 TL;博士

在这种情况下,将__weak对象隐式转换为__strong对象会改变程序的语义,这是编译器永远不应该做的事情.

场景

我们来举个例子吧

NSError *error;BOol success = [myObject performOperationWithError:&error];if (!success) {    // Report the error}

在这种情况下,错误局部变量由ARC自动推断为__strong.

同时出现错误参数

-(BOol)performOperationWithError:(NSError * __autoreleasing *)error;

属于NSError * __autoreleasing *类型.

请注意,在任何情况下,ARC都会将通过引用传递的参数(ID *)推断为类型为ID __autoreleasing *,因此上述签名相当于

-(BOol)performOperationWithError:(NSError **)error;

在ARC下.

因此我们将不匹配,因为我们将__strong带注释的变量传递给期望__autoreleasing参数的方法.

在引擎盖下

在我们的示例中,编译器将通过创建本地__autoreleasing tmp变量来解决此类不匹配问题.

代码变成了

NSError * __strong error;NSError * __autoreleasing tmp = error;BOol success = [myObject performOperationWithError:&tmp];error = tmp;if (!success) {    // Report the error.}

替代

我们现在假装我们可以更改performOperationWithError的签名:

如果我们想避免使用tmp变量的“编译器技巧”,我们可以将我们的签名声明

-(BOol)performOperationWithError:(NSError * __strong *)error;

我们有一个__strong变量,我们现在将它传递给一个期望__strong参数的方法,所以我们只是消除了不匹配.

看起来不错,为什么不总是声明__strong参数?

一个原因是将参数声明为__autoreleasing将使该方法甚至接受__weak引用.

在当前的例子中它没有多大意义,但是在某些情况下我们希望通过引用传递一个__weak变量并声明__autoreleasing(或让ARC推断它)将允许我们这样做.

ARC将应用上面看到的相同技巧,创建一个__autoreleasing tmp变量.

结论

到目前为止提出的机制是以pass-by-writeback的名义进行的.

这种机制设计用于__autoreleasing,__strong和__weak变量,这样程序员可以安全地依赖编译器进行的类型推断,而不必过多关注注释变量.

在某些情况下声明ID __strong *参数可能有意义,但通常它可能会导致编译器生成意外错误.

我的建议是:“让编译器发挥他的魔力,你会很好”

更新

I don’t see why compiler can not do the same trick for __strong argument.

告诉编译器以__autoreleasing方式处理__strong或__weak变量的管理它没关系,因为它基本上意味着:“请,编译器,自动做正确的事情”.

这就是为什么上面看到的技巧可以毫无问题地运作.

另一方面,如果你将一个变量声明为__weak,你可能有充分的理由这么做,而你想要的最后一件事就是在你明确指出的时候隐含地保留它.这将从根本上改变你所编写的代码片段的语义,因此编译器不会这样做(感谢上帝!).

换一种说法

__weak – > __autoreleasing好__strong – > __autoreleasing好__weak< - > __strong错了!

总结

以上是内存溢出为你收集整理的objective-c – 声明方法参数__autoreleasing有什么好处?全部内容,希望文章能够帮你解决objective-c – 声明方法参数__autoreleasing有什么好处?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1243323.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存