Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to treat Disposables correct in project with RxSwift?

When I started to use RxSwift I used to create BaseViewController and extend it with all my controllers where I use RxSwift. The code of BaseViewController.swift:

class BaseViewController: UIViewController {
var mSubscriptions: CompositeDisposable?

func addSubscription(subscription: Disposable){
    if(mSubscriptions == nil){
        mSubscriptions = CompositeDisposable()
    }
    if let mSub = mSubscriptions{
        mSub.addDisposable(subscription)
    }
}

func unsubscribeAll(){
    if let mSub = mSubscriptions{
        mSub.dispose()
        mSubscriptions = nil
    }

}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    unsubscribeAll()
}

deinit{
    unsubscribeAll()
}
}

And I use addSubscription(:_) method everywhere in my child controllers. For example a piece of code from:

class TasksViewController: BaseViewController{
   overrided func viewWillAppear(){
       //...
     var subscribe = dataLoader.load(requestNetwork, dataManager: taskDataManager)
    .observeOn(ConcurrentDispatchQueueScheduler(queue: queue))
    .subscribe({ (event) -> Void in
        //...

    })
    addSubscription(subscribe!)
   }
} 

What if I do not use BaseViewController and just create an instance of DisposeBag() in every controller and add all my subscriptions to that disposeBag? And how should I treat Disposables correct?

like image 418
Marina Avatar asked Jun 10 '16 11:06

Marina


1 Answers

You could just add a let disposeBag = DisposeBag() property to your view controllers. Adding Disposables to that is all you need to do. DisposeBag is like a CompositeDisposeBag that will dispose the Disposables for you when DisposeBag is deallocated (which will happen when the UIViewController is deallocated). There's no need to manage it manually.

However, you can continue to use a subclass if you wanted:

class BaseViewController: UIViewController {
    let disposeBag = DisposeBag()
}

And then to use it:

override func viewDidLoad() {
    super.viewDidLoad()

    Observable.just(42)
        .subscribeNext { i in
            print(i)
        }
        .addDisposableTo(disposeBag)
}

This is in fact what ViewController base class does in RxExample:

property in ViewController

Usage in a subclass

If you're actually wanting to be able to deallocate everything manually (as you were doing with unsubscribeAll), then you can just set the disposeBag to nil or a new DisposeBag so that it gets deallocated: disposeBag = DisposeBag() or disposeBag = nil.

like image 196
solidcell Avatar answered Nov 01 '22 16:11

solidcell