2016-09-21 17 views
5

我使用Xcode 8將代碼轉換爲Swift,但編譯器警告在使用閉包語法在Swift 2.3中創建的一些嵌套函數中添加@escape。我已經發現了一些其他關鍵字也@noescape@autoclosure,但我有這方面的一些問題:@noescape,@ escaping和@autoclosure有什麼區別?

  1. 這是什麼關鍵字的功能性需求?
  2. 什麼是寫作的影響@escaping
  3. 有必要寫嗎?
  4. @autoclosure的行爲與@escape的行爲相同嗎?
  5. 何時使用哪個關鍵字以及爲什麼?

這裏是Swift-evolution文件,但沒有太多從它。

+0

我剛剛注意到你已經標記了Swift 3的問題。在Swift 3中沒有'@ noescape'或'@ escape'。 – Sulthan

回答

9

最重要的區別在於@escaping@noescaping(在Swift 3中沒有這樣的關鍵字!)。當閉包被標記爲@noescape時,可以確定閉包不會被該方法保留(例如執行異步調用),因此您不必擔心所有權週期(還有其他一些次要優點)。

@escaping關閉可以在將來保存或調用,因此您必須確保正確處理所有權(例如[weak self])。

對於@autoclosure參見How to use Swift @autoclosure。總之,在某些情況下,它允許您在封閉物周圍跳過括號。

Swift 3中的默認值(當未指定時)爲@noescaping(請參閱rationale)。他們的關鍵字實際上不再存在。只有@escaping

+1

不錯的答案,如果你會添加代碼示例,所以其他人會對三個關鍵字有更好的理解。謝謝 – technerd

3

@escape表示您的函數可以在方法結束後調用。 @noescape意味着你的閉包將在它傳遞給它的函數結束之前被調用。 @autoclosure表示您可以省略寫入閉合括號,但它會自動變爲@noescape@autoclosure在表達式周圍創建一個自動閉包。所以當調用者寫入一個像2> 1這樣的表達式時,它會在被傳遞給某個函數之前被自動封裝到一個閉包中變成{2> 1}。

2 - 編譯器更容易執行優化。

3 - 尤爲明顯寫,給編譯器(或其他人在使用你的函數)的信息將其與封閉

4的行爲 - 沒有

5 - 對答案的頂部描述

+0

很好的解釋 –