//一种能使闭包“逃逸”出函数的方法是,将这个闭包保存在一个函数外部定义的变量中。
//这里是一个闭包数组
typealias completionHandlerBlock = () -> Void
var completionHandlers: [completionHandlerBlock] = []
class SomeClass {
var x = 10
func doSomething() {
someFunctionWith_Escaping_Closure { self.x = 200 } //将一个闭包标记为 @escaping 意味着你必须在闭包中显式地引用 self。
someFunctionWith_Non_Escaping_Closure { x = 200 } //不带self
}
//逃逸闭包
func someFunctionWith_Escaping_Closure(completionHandler: @escaping completionHandlerBlock) {
//函数接受一个闭包作为参数,该闭包被添加到一个函数外定义的数组中。如果你不将这个参数标记为 @escaping,就会得到一个编译错误。
completionHandlers.append(completionHandler)
}
//非逃逸闭包
func someFunctionWith_Non_Escaping_Closure(closure: () -> Void) {
//该闭包是一个非逃逸闭包,这意味着它可以隐式引用 self。同时无法保存在外部
completionHandlers.append(closure) //报错 : Passing non-escaping parameter 'closure' to function expecting an @escaping closure
closure()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let instance = SomeClass()
instance.doSomething()
print(instance.x) // 打印出 "200"
completionHandlers.first?()
print(instance.x) // 打印出 "100"
}