2014-09-22 50 views
10

我正試圖解決在Swift中基於閉包的強參考循環。
在下面的代碼中,對象由擁有的視圖控制器保留。 ProgressHUDUIView,它也由擁有的視圖控制器保留。每次調用完成處理程序時,ProgressHUD都會泄漏。當使用新的閉包捕獲功能時,聲明自己爲弱或無主無法解決內存泄漏問題。Swift Closures - 捕捉自我弱

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD?.hide(false) 
} 

但是,如果我宣佈一個弱無功爲關閉之外的自我,它修復了內存泄漏,就像這樣:

weak var weakSelf = self 
object.setCompletionHandler { (error) -> Void in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 

任何想法,這是爲什麼不與斯威夫特拍攝工作?

+0

不應該有一個保留週期 – newacct 2014-10-15 00:41:41

回答

-3

嘗試以下操作:

object.setCompletionHandler { [unowned self] (error) ->() in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 
+0

正如原文章中指出,無論是弱或無主解決了內存泄漏。不過謝謝。 – 2014-10-14 10:57:27

11

如果您分配一個閉合的類實例的屬性,並關閉參照實例或它的成員捕獲實例,您將創建一個有力的參考週期關閉和實例之間。 Swift使用捕獲列表來打破這些強大的參考週期。 source Apple

source sketchyTech首先,它明確指出,這整個問題只涉及我們正在分配「封閉的類實例的屬性」封是非常重要的。請記住每條規則。 規則:

  1. 使用弱捕捉如果類實例或屬性是一個可選
  2. 使用無主如果類實例或屬性是不可選的,並且不能設置爲無
  3. 「你必須...使用in關鍵字,即使您省略參數名稱,參數類型和返回類型「

在回答您的問題時,應該沒有保留週期。

4

你說progressHUD由所擁有的視圖控制器(個體經營)保留,你引用它在你關閉......所以把它添加到捕獲列表,然後在封閉使用拍攝的變量,如下所示:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD.hide(false) 
} 
+0

無主的引用被隱式解包,所以'self?.tableView'應該改爲'self.tableView'。 – 2016-08-30 12:33:12

+0

你是正確的@zxzxlch,我已經編輯我的解決方案,通過改變無主自我弱自我,並從捕獲列表中刪除progressHUD。應該沒有保留週期。 – dferrero 2016-08-31 19:58:20

-1

這是我怎麼一直在做:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if let weakSelf = self { 
     if (!error) { 
      weakSelf.tableView.reloadData() 
     } 

     weakSelf.progressHUD?.hide(false) 
    } 
} 
+3

這完全是倒退。將'weakSelf'重命名爲'strongSelf'。 '讓'給你一個強有力的參考。 – 2016-05-05 18:37:50