我有一个看起来像这样的函数:
func test(closure: () -> ()) {
let localClosure = { closure() }
localClosure()
}
这只是一个例子,并没有完全反映我遇到的问题,显然我可以直接调用closure
!
应该很清楚,在上面的代码中,closure
无法逃脱。但是,我收到错误:
关闭使用非转义参数'closure'可能允许它转义
现在,如果localClosure
以某种方式逃脱,我会理解这个错误,但它并没有逃脱。我甚至尝试将localClosure
注释为@noescape
(即使该属性在Swift 3中已弃用),并根据我得到的警告:
@noescape是默认,已弃用
如果localClosure
默认情况下是非转义的,那么为什么另一个非转义闭包不能进入呢?或者这是编译器的错误/限制?
答案 0 :(得分:5)
@escaping
,默认为"如果
localClosure
默认情况下是非逃避,那么为什么......"
根据以下评论中的讨论(感谢@Hamish),我们可以在Swift 3.0中声明以下有关非参数闭包†的事实:
@escaping
。由于@noescape
在Swift 3中已弃用(请参阅例如Xcode 8 release notes或Swift evolution proposal SE-0103),这意味着如果不使用已弃用的方法,则不能使非参数闭包非转义。@noescape
属性是一个缺失的特征(有点回归,因为这不是Swift 2.2中的限制),但是不一定要在将来实施(如果我要理解苹果开发人员乔丹·罗斯在链接进化线程中的答案)。但是,我们仍然可以(仍然)将已弃用的@noescape
属性应用于非参数闭包以使其无法转义,但会显着提示不正确的警告(如下所示,强调我的),现在已被@Hamish报告为bug,请参阅bug report SR-2969。
"
@noescape
是默认,已弃用"
总而言之,localClosure
是@escaping
,这自然意味着不能允许它包装closure
的非转义闭包参数test(...)
。
<子> [†]通过非参数闭包,我指的是函数的 not 参数的所有闭包,即 not 作为参数提供给函数的闭包。 子>
作为旁注,您可能已经知道了问题:如果我们希望按照您的示例处理/换行,我们可以自然地将closure
标记为@escaping
。
func test(closure: @escaping () -> ()) -> () -> () {
let escapingLocalClosure = { closure() }
return escapingLocalClosure
}