简体   繁体   English

DisposeBag内存泄漏?

[英]DisposeBag memory leak?

I inherited a project that uses disposeBags everywhere, but disposeBag seems to be a massive memory leak. 我继承了一个在所有地方都使用disposeBags的项目,但是disposeBag似乎是一个巨大的内存泄漏。 None of the view controllers utilizing the bag ever get deallocated, which leads to subscriptions piling up. 没有一个使用该包的视图控制器被释放,这导致订阅堆积。 I'm

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

The key issue is the reference in the handler to "self." 关键问题是处理程序中对“自我”的引用。
My theory is that self is a strong reference, which is leading to a situation where even when the view controller gets popped and there are no other references to the view controller, it still doesn't get deallocated because the bag has a strong reference to it. 我的理论是self是一个强引用,这会导致一种情况,即使弹出视图控制器并且没有其他对视图控制器的引用,它仍然不会被释放,因为包对它。 Circular logic where the bag doesn't get disposed because the VC doesn't dealloc and the VC doesn't dealloc because the bag doesn't get disposed. 循环逻辑,其中由于VC不会取消分配而不会处理袋子,而VC由于不会处理袋子而不会使VC释放,因此不会处理袋子。

The commented out line 注释行

//self.disposeBag = DisposeBag()

when called allows for the view to properly dealloc. 调用时允许视图正确地释放。

On top of the memory leak, the issue that I'm facing is that I don't want to dispose the bag on viewWillDisappear, but rather when the view is popped. 除了内存泄漏之外,我面临的问题是我不想将包放置在viewWillDisappear上,而是在弹出视图时放置。 I need it to stick around if I add a view on top in case I pop back to this view. 如果我在顶部添加一个视图,以防我跳回到该视图,则需要它坚持住。

Any help would be greatly appreciated! 任何帮助将不胜感激!

Your theory is correct. 你的理论是正确的。 You need to use a weak or unowned reference to self in your subscribe methods rather than a strong reference. 您需要在订阅方法中使用弱引用或无主引用来自身,而不要使用强引用。 And get rid of the assignment to disposeBag in the viewWillDissapear. 并摆脱viewWillDissapear中的disposeBag的分配。 The disposeBag will properly dispose of your subscribers when the object gets deinted. 当对象被指定时,disposeBag将正确处置您的订阅者。

You setup a weak reference to self like this: 您可以这样设置对自身的弱引用:

   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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM