//一种能使闭包“逃逸”出函数的方法是,将这个闭包保存在一个函数外部定义的变量中。
//这里是一个闭包数组
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"
    }
 
12-23 06:43