1. 程式人生 > >swift 逃逸閉包 @escaping

swift 逃逸閉包 @escaping

在swift3.0之後閉包預設都是非逃逸的。當一個閉包作為引數被傳入儲存後,等待稍後在呼叫,這樣的閉包就是逃逸的,逃逸閉包必須新增@escaping標註。

 看下面例子:

class ExampleClass {
    var handlers:[()->Void] = []
    func someEscapingFunc(closure:@escaping ()->Void)  {
        handlers.append(closure)
    }
    
}
someEscapingFunc方法傳入一個閉包,這個閉包沒有立即執行而是被handlers儲存了,這種就是閉包就是逃逸的,必須加@escaping標註。

在逃逸閉包中使用不當容易造成記憶體洩漏。

class ViewController: UIViewController {

    var x = 0
    let example = ExampleClass()
    override func viewDidLoad() {
        super.viewDidLoad()
        example.someEscapingFunc{[weak self] in
            self?.x = 10
        }

    }

}
我必須這樣呼叫才能避免造成記憶體洩漏。

逃逸閉包self不能隱試引用,但是在逃逸閉包中self可以隱試引用。舉個例子

class ExampleClass {
    var handlers:[()->Void] = []
    func someEscapingFunc(closure:()->Void)  {
        closure()
    }
    
}

class ViewController: UIViewController {
    
    var x = 0
    
    let example = ExampleClass()
    override func viewDidLoad() {
        super.viewDidLoad()
        example.someEscapingFunc {
            x = 10
        }
        
    }
}
像上面那樣呼叫,不用謝self。而且非逃逸閉包不會造成記憶體洩漏。