RxSwiftのdisposeについて3分で理解


RxSwiftのdisponeについて3分で理解出来るようにまとめました。
公式ドキュメントを翻訳しました。

Disposing

observed sequenceが終了する条件がもう一つある。Sequenceを行い、計算に割り当てられた全てのリソースを解き放つ時、我々はsubscriptionに対してdisposeを呼ぶ事ができる。

要するに、disposeメソッドを呼ぶ事でRxSwiftのObservableを終了できる。
以下はinterval オペレーターにdisposeを使用した例だ。
毎0.3秒事に数字をプリントアウトするコードだが、開始から2秒後にdisposeが呼ばれているため、5回数字をプリントしている。


let scheduler = SerialDispatchQueueScheduler(qos: .default)
let subscription = Observable<Int>.interval(.milliseconds(300), scheduler: scheduler)
    .subscribe { event in
        print(event)
    }

Thread.sleep(forTimeInterval: 2.0)

subscription.dispose()
This will print:

0
1
2
3
4
5

いつも手動でdisposeを呼ばなくて良い事に注意してください。上の例は学習用のサンプルコードです。disposeを手動で呼ぶことは、バッドプラクティスです。subscriptionをdisposeするDisposeBagや、takeUtil オペレーターのようなもっと良いやり方があります。

このコードはdisposeが実行された後も何かprintするでしょうか?
この問いの答えば「状況による」です。
もし、schedulerが、serial scheduler(MainSchedulerなど)でdisposeが同じserial schedulerに呼ばれたら答えはNoです。
その他の状況ではYesです。

並列処理を行うには二つのシンプルな方法があります。
・elementを生成する。
・subscriptionをdisposeする。
disposeを実行した後に後に何かプリントしますか?という問いは、scedulerの種類によって違うため意味がありません。

例えば以下のようなコードなら


let subscription = Observable<Int>.interval(.milliseconds(300), scheduler: scheduler)
            .observeOn(MainScheduler.instance)
            .subscribe { event in
                print(event)
            }

// ....

subscription.dispose() // called from main thread

disposeが呼ばれた後、何もプリントされません。

以下のようなケースでも、


let subscription = Observable<Int>.interval(.milliseconds(300), scheduler: scheduler)
            .observeOn(serialScheduler)
            .subscribe { event in
                print(event)
            }

// ...

subscription.dispose() // executing on same `serialScheduler`

disposeが呼ばれた後、何もプリントされません

参考