I inherited a project that uses disposeBags everywhere, but disposeBag seems to be a massive memory leak. 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. 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.
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. 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!