嘗試理解Swift中的@escaping

要理解@escaping,首先需要理解closure, 要理解closure,首先理解匿名函數。

先理解匿名函數

要在Swift中構造匿名函數,需要:

  1. 創建函數體,包括花括號,但是不需要函數聲明
  2. 如果必要,將函數的參數列表與返回類型作為花括號中的第一行,后跟關鍵字in.

例子1: 將以下函數變成匿名函數:

func whatToAnimate(){
    self.myButton.frame.origin.y += 20
}

匿名函數版本:

{
    () -> () in
    self.myButton.frame.origin.y += 20
}

例子2: 有參數的具名函數:

func whatToDoLater(finished: Bool){
    print("finished: \(finished)")
}

匿名函數版本:

{
    (finished: Bool) -> () in
    print("finished: \(finished)")
}

可省略的地方:

  1. 省略返回類型
  2. 沒有參數可以省略 in 這一樣
  3. 省略參數類型
  4. 省略圓括號,這個是如果就一個參數,并且我們編譯器可以推斷出其類型的話
  5. 省略 in, 直接用名字比如 $0
  6. 省略參數名,用_代替
  7. 省略函數實參標簽(又叫尾函數
    ...

一路省略下來,匿名函數真是節約。

再理解閉包

理解匿名函數之后,我們來看閉包的表達式:

{ (parameters) -> return type in
    statements
}

這就是匿名函數啊,而我們叫它閉包則是因為:

閉包可以捕獲和存儲其所在上下文中任意常量和變量的引用。 這就是所謂的閉合并包裹著這些常量和變量,俗稱閉包。

而在這一篇中,我們可以一步一步看到如何從

reversed = sorted(names, { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

利用省略到:

reversed = sorted(names, >)

再利用 trailling closure的特性,可以這樣:

reversed = sorted(names) { $0 > $1 }

閉包當然還有更好的例子,因為我們來看它的一些特性。

Escaping Closure(逃逸閉包

如果一個閉包被作為一個參數傳遞給一個函數,并且在函數return之后才被喚起執行,那么這個閉包是逃逸閉包。

好抽象的描述,這篇文章寫得不錯:

不逃逸閉包的生命周期:

  1. Pass a closure into a function
  2. The function runs the closure (or not)
  3. The function returns

然后這個closure就死掉了。

而逃逸閉包則會一直存在,沒有因為function被kill而死掉,所以我們叫這個閉包為逃逸閉包(?

在以下的兩種情況,我們需要使用 escaping closure:

  1. 異步execution,并不能說函數return了就把closure kill掉,因為這個closure可能還沒有執行完畢
  2. 存儲,如果任何全局變量都有一些些存儲存在,那么這個closure也被逃逸掉了。

在 Swift 1 和 2中, closure by default 是 escaping的,所以我們需要用 @noescape 來mark.
在 Swift 3中,closure by default是non-escaping,我們需要用@escaping 來mark

In Swift 3, closure parameters are non-escaping by default; you can use the new @escaping attribute if this isn’t what you want. Non-escaping closures passed in as arguments are guaranteed to not stick around once the function returns.

而一般情況下,弱??就跟著Xcode的提示走?

參考:

  1. <iOS 9 Programming Fundamentals with Swift> by Matt Neuburg
  2. 閉包
  3. Escaping and Nonescaping Closures in Swift 3
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 86.復合 Cases 共享相同代碼塊的多個switch 分支 分支可以合并, 寫在分支后用逗號分開。如果任何模式...
    無灃閱讀 1,412評論 1 5
  • 以下翻譯自Apple官方文檔,結合自己的理解記錄下來。翻譯基于 swift 3.0.1 原文地址 Closure...
    藝術農閱讀 1,596評論 0 3
  • 前言:swift是一門很優雅,很簡潔,功能很強大的語言,同時也是一門很復雜的語言。進門比較簡單,看完蘋果官方的文檔...
    一劍孤城閱讀 6,133評論 0 10
  • 愛情的炙熱,如同滑過天空的流星,那樣絢麗迷人。伴著融化一切的熱,在天空中展現出那世間最美的景色 流星的熱可以譬美永...
    雨夜聆聽者閱讀 210評論 0 0
  • 文/葉丹穎 1 你是原點 從你的坐標點出發 我開始重新打探這世界 你是我愛上這個世界的全部理由 2 我是個只愿意對...
    樹姑娘閱讀 443評論 0 4