2017-06-01 1 views
1

J'ai hérité d'un projet qui utilise dispoBags partout, mais disposeBag semble être une fuite de mémoire massive. Aucun des contrôleurs de vue utilisant le sac n'est jamais désalloué, ce qui conduit à des empilements d'abonnements. Je suisDisposeBag fuite de mémoire?

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") 
    } 
} 

Le problème clé est la référence dans le gestionnaire à "self". Ma théorie est que self est une référence forte, ce qui conduit à une situation où, même lorsque le contrôleur de vue se déclenche et qu'il n'y a pas d'autres références au contrôleur de vue, il ne se désaffecte toujours pas parce que le sac a une forte référence à celui-ci. Logique circulaire où le sac n'est pas disposé car le VC ne se décharge pas et le VC ne le libère pas car le sac n'est pas disposé.

La ligne commentée

//self.disposeBag = DisposeBag() 

quand appelé permet la vue de dealloc correctement. En plus de la fuite de mémoire, le problème auquel je suis confronté est que je ne veux pas jeter le sac sur viewWillDisappear, mais plutôt lorsque la vue est désactivée. J'en ai besoin pour rester si j'ajoute une vue sur le dessus au cas où je retournerais à cette vue.

Toute aide serait grandement appréciée!

+0

Par ailleurs, il n'y a pas que des références à des éléments de l'interface utilisateur, si je parlais à un self.testString variable au lieu de self.testLabel.text , il résulterait toujours le VC ne pas être disposé – Mars

Répondre

1

Votre théorie est correcte. Vous devez utiliser une référence faible ou sans référence à vous-même dans vos méthodes d'abonnement plutôt qu'une référence forte. Et se débarrasser de l'affectation de disposerBag dans viewWillDissapear. Le disposBag disposera correctement de vos abonnés lorsque l'objet sera débloqué.

configuration Vous une référence faible à l'auto comme ceci:

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

J'ai essayé de changer le gestionnaire à: faible var selfie = self, selfie? .holder.text = "Test text2" mais il n'est toujours pas disposé. – Mars

+0

J'ai également essayé de changer le gestionnaire à: unowned var selfie = self, selfie.holder.text = "Test text2" mais il n'est toujours pas disposé. – Mars

+0

Impressionnant, "[self unie] test dans" l'a fait, et je suppose que [moi-même faible] fonctionne aussi. C'est vraiment comme si ça devait être le comportement par défaut ... ou est-ce que je manque quelque chose du côté de la théorie de l'application de la disposition? – Mars