【发布时间】:2020-04-29 00:35:57
【问题描述】:
(()->())和@escaping()->void有什么区别?
func foo(_ completion: (() -> ()) { }
func boo(_ completion: @escaping () -> Void) { }
【问题讨论】:
标签: swift escaping closures void swift5
(()->())和@escaping()->void有什么区别?
func foo(_ completion: (() -> ()) { }
func boo(_ completion: @escaping () -> Void) { }
【问题讨论】:
标签: swift escaping closures void swift5
转义闭包
当闭包作为参数传递给函数时,闭包被称为转义函数,但在函数返回后被调用。当您声明一个将闭包作为其参数之一的函数时,您可以在参数类型前写 @escaping 以指示允许闭包转义。
闭包可以逃逸的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数将闭包参数作为完成处理程序。函数在开始操作后返回,但在操作完成之前不会调用闭包——闭包需要转义,以便稍后调用。例如:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
someFunctionWithEscapingClosure(_:) 函数将闭包作为其参数,并将其添加到函数外部声明的数组中。如果你没有用 @escaping 标记这个函数的参数,你会得到一个编译时错误。”
“let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// returns a value of 50
incrementByTen()
// returns a value of 60
上面的例子表明调用alsoIncrementByTen 与调用incrementByTen 是一样的。因为它们都引用同一个闭包,所以它们都递增并返回相同的运行总计。
转义闭包 当闭包作为参数传递给函数时,闭包被称为转义函数,但在函数返回后被调用。当您声明一个将闭包作为其参数之一的函数时,您可以在参数类型前写 @escaping 以指示允许闭包转义。
闭包可以逃逸的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数将闭包参数作为完成处理程序。函数在开始操作后返回,但在操作完成之前不会调用闭包——闭包需要转义,以便稍后调用。例如:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
someFunctionWithEscapingClosure(_:) 函数将闭包作为其参数并将其添加到已声明的数组中[…]”
摘自:Apple Inc. “Swift 编程语言 (Swift 5.2)。”苹果图书。 https://books.apple.com/us/book/the-swift-programming-language-swift-5-2/id881256329
换句话说,如果你试图引用当前对象中的方法,@escaping 闭包需要使用 self。即 SKAction 的完成闭包就是一个很好的例子。
并且非转义闭包不需要使用 self.因为它们不用于引用对象。
【讨论】: