2016-08-17 132 views
3

是否有任何方式向特定方法的「客戶端」指示閉包參數將被保留?Swift指示保留了閉包參數

例如,具有下面的代碼:

import Foundation 

typealias MyClosureType =() -> Void 

final class MyClass { 

    private var myClosure: MyClosureType? 

    func whatever(closure: MyClosureType?) { 
     myClosure = closure 
    } 
} 

任何人都可以開始使用這個類,以及將關閉該方法whatever沒有關於它是否實際上是被保留或沒有任何想法。哪個容易出錯,並可能導致內存泄漏。

例如,「客戶」做這樣的事情,會被永遠不會釋放

final class MyDummyClient { 

    let myInstance = MyClass() 

    func setUp() { 
     myInstance.whatever { 
      self.whateverHandler() 
     } 
    } 

    func whateverHandler() { 
     print("Hey Jude, don't make it bad") 
    } 
} 

這就是爲什麼我想知道是否有什麼辦法可以防止這種類型的錯誤。某些類型的參數,我可以添加到我的方法whatever的定義中,它向客戶提供了關於需要弱化以避免泄漏的提示

回答

2

閉合參數是轉義還是非轉義對於調用者是否可以保留。特別是,一個 - 轉義閉包參數不能保留一個函數調用。

SE-0103,不逃避關閉(當前標記@noescape)將成爲斯威夫特3默認的,你得寫@escaping如果你想保存關閉,所以這樣的情況下將變的更爲明顯。

否則,沒有語言功能來幫助你在這裏。你必須用API設計和文檔來解決這個問題。如果它像處理程序那樣,我會推薦一個屬性,obj.handler = { ... }或者像obj.setHandler({ ... })obj.addHandler({ ... })這樣的方法。這樣一來,在閱讀代碼時,您可以很容易地知道由於=setadd而正在保存關閉。

(事實上,編譯的OBJ-C時,鏘explicitly looks for methods named set...: or add...:確定何時是否警告用戶關於保留週期。這是可能的類似的診斷可以被添加到所述夫特編譯器在未來。)

0

隨着你提出閉包本身的唯一情況是唯一將被保留的情況,所以如果在你打電話時正確添加[弱自己]到閉包,那就不應該有任何問題。

我不確定你想要防範什麼問題,但你也可能關於使用委託(協議)而不是閉包。