@noescape、@escaping和@autoclosure之间有什么区别?

9

我正在使用Xcode 8将代码转换为Swift,但编译器警告要在一些已经在Swift 2.3中创建的嵌套函数中添加@escape,使用闭包语法。 我还发现其他一些关键字,如@noescape@autoclosure,但我有一些问题:

  1. 这个关键字有什么功能需求?
  2. 编写@escaping的影响是什么?
  3. 需要编写吗?
  4. @autoclosure是否与@escape行为相同?
  5. 何时使用哪个关键字以及原因?

这里是Swift-evolution文档,但其中并没有太多内容。


我刚刚注意到你已经标记了Swift 3的问题。在Swift 3中没有@noescape@escape - Sulthan
2个回答

13
最重要的区别在于@escaping@noescaping(Swift 3中没有这个关键字!)。当闭包被标记为@noescape时,您可以确信该闭包不会被方法保留(例如执行异步调用),因此您无需担心所有权循环(还有其他一些次要的好处)。 @escaping闭包有时可以保存或在将来调用,因此您必须确保正确处理所有权(例如[weak self])。
有关@autoclosure的详细信息,请参见如何使用Swift @ autoclosure。简而言之,它允许您在某些情况下跳过闭包周围的大括号。
默认值(未指定时)在Swift 3中是@noescaping(请参见理由)。该关键字实际上不再存在,现在只有@escaping

1
很好的回答,如果您能添加代码示例,那么其他人对这三个关键字会有更好的理解。谢谢。 - technerd

6
@escape 表示你的函数可以在方法结束后被调用。 @noescape 表示你的闭包将在传递给函数之前被调用。 @autoclosure 表示你可以省略写闭包括号,但它会自动变成 @noescape@autoclosure 在表达式周围创建一个自动闭包。因此,当调用者写下类似 2 > 1 的表达式时,它会自动包装成 {2 > 1} 的闭包,然后再传递给某个函数。
2 - 更容易进行编译器优化。
3 - 更好的编写方式,可以为编译器(或任何使用你的函数的人)提供有关它在闭包方面的行为的信息。
4 - 不是。
5 - 在本答案顶部有描述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接