[英]Swift optional escaping closure
编译器错误Closure use of non-escaping parameter 'completion' may allow it to escape
,这是有道理的,因为它将在函数返回后调用。
func sync(completion:(()->())) {
self.remoteConfig.fetch(withExpirationDuration: TimeInterval(expirationDuration)) { (status, error) -> Void in
completion()
}
}
但是,如果我将闭包设为可选,则不会出现编译器错误,那是为什么呢? 函数返回后仍可以调用闭包。
func sync(completion:(()->())?) {
self.remoteConfig.fetch(withExpirationDuration: TimeInterval(expirationDuration)) { (status, error) -> Void in
completion?()
}
}
将闭包包装在Optional中会自动将其转义。 从技术上讲,它已经被嵌入枚举(“可选”)“转义”了。
为了理解这种情况,实现以下代码将很有用:
typealias completion = () -> ()
enum CompletionHandler {
case success
case failure
static var handler: completion {
get { return { } }
set { }
}
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler.handler = handlerParameter
}
乍一看,此代码似乎合法,但事实并非如此! 您将收到编译时错误抱怨:
错误 :将非转义参数'handlerParameter'分配给@转义闭包
让chObject = CompletionHandler.handler = handlerParameter
注意:
注意 :参数'handlerParameter'是隐式非转义函数doSomething(handlerParameter:完成){
这是为什么? 假设代码片段与@escaping
没有@escaping
...
实际上,由于Swift 3已发布,因此默认情况下,如果在enum , struct或class中声明了闭包,则闭包将被“转义”。
作为参考,报告了与该问题有关的错误:
尽管它们可能与本案并非100%相关,但受让人的评论清楚地描述了该案:
第一条评论 :
这里的实际问题是, 可选的闭包现在隐式@转义。
第二条评论 :
不幸的是,Swift 3就是这种情况。这是Swift 3中转义的语义:
1)默认情况下,函数参数位置的闭包不转义
2) 所有其他关闭都在逃逸
因此,所有通用类型参数闭包(例如Array和Optional )都在转义。
显然, Optional
是枚举。
同样-如上所述,相同的行为也适用于类和结构:
类案例:
typealias completion = () -> ()
class CompletionHandler {
var handler: () -> ()
init(handler: () -> ()) {
self.handler = handler
}
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler(handler: handlerParameter)
}
结构案例:
typealias completion = () -> ()
struct CompletionHandler {
var handler: completion
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler(handler: handlerParameter)
}
上面的两个代码段将导致相同的输出(编译时错误)。
为了解决这个问题,您需要让函数签名为 :
func doSomething( handlerParameter: @escaping completion)
因为您期望您必须让completion:(()->())?
为了逃脱,这将自动完成-如上所述-。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.