2016-09-13 38 views
0

我們實現並擴展NSData,將數據異步持久化到URL。 這是一個簡短版本的功能。異步swift函數應該保留對該對象的強引用嗎?

extension NSData { 

    func writeToURL1(url:NSURL, completion:() -> Void) { 

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { [weak self] in 

      guard let strongSelf = self else { return } 

      strongSelf.writeToURL(url, atomically: true) 

      completion() 
      }) 
    } 
} 

下面是我們如何使用它:

var imageData = UIImageJPEGRepresentation(image, 0.8) 
imageData?.writeToURL(someURL) { in ... } 

當然,問題是,如果寫操作完成之前strongSelf將是零imageData被釋放,並完成處理程序將永遠不會被調用。

有兩個解決這一問題。

  1. 在完成塊刪除[weak self](即在writeToURL1的強引用self
  2. 參考imageData(即imageData?.writeToURL(someURL) { in imageData = nil ... }

什麼方法更斯威夫特友好,我們應該選擇什麼方法?

謝謝!

回答

4

您應該如果您不希望物體從腳下離開(並且這樣做不會創建參考週期),請使用強參考。如果你不在意物體是否從腳下離開,那麼它就是一個弱點;如果你需要物體在周圍,並且有強有力的保證,物體不會從你的腳下消失,但是一個強有力的參考會產生一個循環。

在你的情況,你所關心的對象可能會消失,因爲這意味着你將無法保存。由於您不能保證其他東西會保持對象的活動狀態,直到完成任務,您應該使用強引用。

對閉包中的self的強引用是一個問題,因爲它很容易以非顯而易見的引用循環結束,但是您知道引用將在閉包之後立即丟棄執行,所以這不是一個問題。

+0

謝謝。你的答案是完全合理的,我們很可能會選擇選項1.我們之所以走向虛弱自我的原因是我們正在考慮在應用程序範圍內使用它,並希望下一個開發者選擇是否將其保存在內存中,而不是僅僅發送它不知道。這是關於誰可以控制記憶,調用函數或過程本身的人。 –

3

這聽起來像你只是想極力捕捉參考NSData對象,所以去除[weak self]在我看來是最簡單,最好的辦法。通常,使用弱引用來避免在閉包中捕獲時的保留週期。但是,您實際上並未創建保留週期,只是通過在塊中捕獲自己來保留一種方法。該塊不是由自我保留的,它只是將調用堆棧傳遞到dispatch_async中,最終在該塊中調用和釋放該塊。因此,通過使用weak self不存在保留週期,您只需通過閉合發生保留就可以了。也就是說,您希望將數據保存在內存中直到調用閉包。

相關問題