Escaping and Nonescaping Closures in Swift3

本文翻譯自這里

函數與閉包在Swift中作為一等公民,可以存儲持偏,當作參數傳遞驼卖,并且把它們看待成其他的對象或者類型。通常我們將閉包當作發(fā)送API完成后的回調鸿秆。

在Swift3中酌畜,當你將閉包當作一個函數的參數時,會有一個新的建議:編譯器將閉包默認為non-escaping卿叽。下面看看non-escapingeascaping的區(qū)別桥胞。

Non-Escaping Closures

non-escaping的生命周期:

1.將閉包傳遞給函數
2.函數執(zhí)行閉包(或不執(zhí)行)
3.函數返回

non-escaping
non-escaping

這個閉包并沒有“逃逸(escape)”到函數體外恳守。當函數結束時,傳遞的閉包離開函數作用域贩虾,并且沒有其他的引用指向該閉包催烘。

如果考慮到內存的持有和釋放平衡,這個閉包的引用計數在函數結束時和開始時是一樣的缎罢。

Escaping Closures

現(xiàn)在可以猜到escaping closure是什么意思伊群。在函數內,你可以一直運行閉包(或者不)策精;這里有幾種方法來讓閉包逃逸出函數體:

  • 異步操作:如果在一個異步隊列中執(zhí)行閉包舰始,那么這個隊列會一直持有這個閉包。你無法確定閉包何時被執(zhí)行咽袜,并且也無法保證在函數返回前結束閉包丸卷。

  • 存儲:將閉包存儲為全局變量、屬性询刹、或者任何其他的存儲方式谜嫉。

escaping
escaping

Escaping and Non-Escaping in Swift 3

在Swift1和2中,閉包參數默認為escaping范抓。如果能夠確保閉包沒有逃逸出函數體,你可以使用@noescape修飾它食铐。

在Swift3中有些不同匕垫,參數閉包默認修飾為non-escaping

如果閉包修飾為non-escaping虐呻,這里有一些潛在的優(yōu)化象泵。因為閉包不會逃逸,編譯器可以將閉包的存儲和調用優(yōu)化斟叼。

經常碰到的情況就是閉包中持有self的時候:

class ClassA {
     // takes a closure (non-escaping by default) 
     func someMethod(closure: () -> Void) {  
         // secret stuff 
    }
}
class ClassB { 
    let classA = ClassA() 
    var someProperty = "Hello" 
    
    func testClosure() {
         classA.someMethod {
            // self is captured! 
            someProperty = "Inside the closure!" 
        } 
    }
}

當調用someMethod的時候偶惠,記住somePropertyClassB的成員屬性。只有閉包為逃逸閉包的時候才必須使用self朗涩,而這段代碼在Swift3中運行不會有任何問題忽孽。
這個閉包仍然會截獲self,但是因為閉包在函數結束后就會釋放谢床,所以編譯器會知道沒有發(fā)生循環(huán)引用兄一。
如果將代碼改成如下這樣:

func someMethod(closure: @escaping () -> Void) {
     // secret stuff
}

現(xiàn)在這變成另外一種情況,當調用這個方法并且提供一個有引用指向的閉包识腿,在閉包內必須明確使用self來提醒自己這個閉包截獲了當前的self出革。

最后

在Swift3中,閉包參數默認為non-escaping渡讼,根據自己的需求使用@escaping骂束。非逃逸閉包當做參數傳遞時耳璧,在函數返回之前閉包必須執(zhí)行完。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末展箱,一起剝皮案震驚了整個濱河市旨枯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌析藕,老刑警劉巖召廷,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異账胧,居然都是意外死亡竞慢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門治泥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筹煮,“玉大人,你說我怎么就攤上這事居夹“芰剩” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵准脂,是天一觀的道長劫扒。 經常有香客問我,道長狸膏,這世上最難降的妖魔是什么沟饥? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮湾戳,結果婚禮上贤旷,老公的妹妹穿的比我還像新娘。我一直安慰自己砾脑,他們只是感情好幼驶,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著韧衣,像睡著了一般盅藻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畅铭,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天萧求,我揣著相機與錄音,去河邊找鬼顶瞒。 笑死夸政,一個胖子當著我的面吹牛,可吹牛的內容都是我干的榴徐。 我是一名探鬼主播守问,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼匀归,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耗帕?” 一聲冷哼從身側響起穆端,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仿便,沒想到半個月后体啰,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡嗽仪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年荒勇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闻坚。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡沽翔,死狀恐怖,靈堂內的尸體忽然破棺而出窿凤,到底是詐尸還是另有隱情仅偎,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布雳殊,位于F島的核電站橘沥,受9級特大地震影響,放射性物質發(fā)生泄漏夯秃。R本人自食惡果不足惜座咆,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寝并。 院中可真熱鬧箫措,春花似錦腹备、人聲如沸衬潦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镀岛。三九已至,卻和暖如春友驮,著一層夾襖步出監(jiān)牢的瞬間漂羊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工卸留, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留走越,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓耻瑟,卻偏偏與公主長得像旨指,于是被迫代替她去往敵國和親赏酥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內容