2017-06-01 74 views
1

我繼承了一個使用disposeBags的項目,但disposeBag似乎是一個巨大的內存泄漏。利用這個包的視圖控制器都沒有被釋放,導致訂閱堆積。我是DisposeBag內存泄漏?

class TestViewController: UIViewController 
{ 

    @IBOutlet weak var testLabel: UILabel! 
    var basePresenter: BasePresenter = BasePresenter() 
    var disposeBag: DisposeBag = DisposeBag() 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     bindPresenter() 
    } 

    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 
     //self.disposeBag = DisposeBag()     <------------ 
    } 

    func bindPresenter() { 
     //super.bindPresenter() 
     basePresenter.testVariable.asDriver().drive(onNext: { test in 
      if !test.id.isEmpty { 
       self.testLabel.text = "Test text"  //<------------ 
      } 
     }).addDisposableTo(disposeBag) 
    } 

    deinit{ 
     print("TestView was dealloc'd") 
    } 
} 

關鍵問題是處理程序中對「自我」的引用。
我的理論是,自我是一個強大的參考,這導致了即使視圖控制器彈出並且沒有其他對視圖控制器的引用的情況下,它仍然不會被取消分配,因爲包具有強壯參考它。循環邏輯,由於VC不會解除分配,並且VC不會釋放,因爲袋子沒有被丟棄,所以袋子不會被丟棄。

的註釋行

//self.disposeBag = DisposeBag() 

調用時允許適當的dealloc視圖。

在內存泄漏之上,我面臨的問題是我不想將包放置在viewWillDisappear上,而是在彈出視圖時。如果我在頂部添加視圖以便回到此視圖,我需要它堅持下去。

任何幫助將不勝感激!

+0

順便說一句,它不是UI元素只是參考,如果我提到了一個變量,而不是self.testString的self.testLabel.text ,它仍然會導致VC沒有被處置 – Mars

回答

1

你的理論是正確的。你需要在你的訂閱方法中使用對自我的弱或無主的引用,而不是強有力的引用。並且在viewWillDissapear中擺脫disposeBag的任務。當對象被刪除時,disposeBag會正確地處理你的用戶。

您設置一個弱引用自這樣的:

basePresenter.testVariable.asDriver().drive(onNext: { [weak self] test in 
     if !test.id.isEmpty { 
      self?.testLabel.text = "Test text" // no longer a strong reference 
     } 
    }).disposed(by: disposeBag) 
+0

我試着將處理程序更改爲: weak var selfie = self, selfie?.holder.text =「Test text2」 但它仍未處理。 – Mars

+0

我也嘗試更改處理程序爲: unowned var selfie = self, selfie.holder.text =「Test text2」 但它仍未處理。 – Mars

+0

真棒,「[無主自我]測試」做到了,我假設[虛弱的自我]也有效。這真的覺得它應該是默認的行爲......或者我在disposebag應用理論方面丟失了什麼? – Mars