這個寫了不知道多少遍的東西后邊寫著寫著就不知道為什么寫了. 而且有時候完全依靠編譯器的提醒使用補全功能添加.
其實它是一個非常簡單的概念
If a closure is passed as an argument to a function and it is invoked after the function returns, the closure is escaping.
如果一個閉包作為函數(shù)的參數(shù), 并且在這個函數(shù)執(zhí)行完畢之前沒有執(zhí)行, 這個閉包就是逃逸閉包
我們大部分時候使用閉包作為參數(shù)的目的一般主要是異步回調(diào), 這種情況肯定是在這個函數(shù)的作用域之外的(不然就是一個同步執(zhí)行的閉包)
所以這個標識的意思就是,"注意! 我這個閉包不確定什么時候要調(diào)用, 為了我調(diào)用時候能夠正確執(zhí)行, 我要捕獲閉包里用到的變量了!"
反之, 如果一個閉包參數(shù)并沒有被@escaping標識, 它其實是不會捕獲外部變量, 也不需要弱引用修飾對應變量.
比如
func fetchSomeData(_ completion: () -> Void) {
completion()
}
override func viewDidLoad() {
super.viewDidLoad()
fetchSomeData {
print(title) // Don't need `self`.title
}
}
這是一個無意義的示例. 但我們應該注意到了平常用的map filter函數(shù)都不需要內(nèi)部顯式self 它們都是同步的不捕獲任何變量的閉包
結論
編譯器會根據(jù)這個修飾符對閉包以及內(nèi)部變量做出不一樣的內(nèi)存管理. 我們也應該意識到其中的區(qū)別來做出不同的處理. 無腦加weak 并不是我們想要的.