RxSwiftをざっくりと理解する(1)基礎用語まとめ


はじめに

andfactory Advent Calendar 23日目の記事です!
RxSwiftの内容を初学者に向けてざっくりとまとめてみました。
第1回は基礎用語です。

Observable

それを購読(≒監視)しているオブジェクトに処理されるデータを流すもの。
* Observableはelementを含むnextイベントを流すことができる。
* terminateイベント(error, completed)が流れるまで続く。
* Observableが停止するとイベントは流れなくなる。

Subscribe

Observableを購読(≒監視)すること。
onNext,onError,onCompleted,onDisposedのタイミングで行いたい処理を登録することができる。

Disposable

メモリリーク防止のために必要であれば購読を解除してくれるオブジェクト


  let observable = Observable.of(1, 2, 3)

  observable
    .subscribe(
        onNext: { element in
            // 値が流れてきたときの処理
        },
        onError: { error in
            // エラー時の処理
        },
        onCompleted: {
            // completeイベントが流れたときの処理
        },
        onDisposed: {
            // disposeされたときの処理
        })
   .disposed(by: disposeBag)

Traits

通常のObservableより機能を限定したもの。
* コードの意図をより明確に伝えるのに役立つ。
* Single,Maybe,Completableの3つがある。
* Singleは success(value) か error しか流さないため、API通信などに便利。

class Reader {
    static func loadData(from data: String) -> Single<String> { // 略 }
}

Reader.loadData(from: "text")
    .subscribe(
        onSuccess: { text in
            print(text)
        },
        onError: { error in
            // エラー処理
    })
    .disposed(by: disposeBag)

Subjects

ObserverとObservableの両方の役割を持てる。
RxSwiftにおいて4つのSubjectとそれをラップした2つのRelayがある。
* PublishSubject -> 初期値は持たない。購読者に対して新しいeventのみを流す。
* BehaviorSubject -> 初期値を持つ。最新の値を新たな購読者に対して流す。
* ReplaySubject -> バッファサイズを持って初期化される。そのサイズ分だけ値を保持して新たな購読者に流す。

let subject = ReplaySubject<String>.create(bufferSize: 2)

subject.onNext("a")
subject.onNext("b")
subject.onNext("c")

subject
    .subscribe {
        print($0)
        // bとcがプリントされる
    }
    .disposed(by: disposeBag)

  • AsyncSubject -> completedを受け取ると、nextイベントの最後の値だけを流す。あまり使われない?
  • PublishRelay / BehaviorRelay -> それぞれPublishSubjectとBehaviorSubjectのラッパー。
  • nextイベントのみを流せる。relayに対して.completedや.errorを流すことはできない。
  • subjectをクラスの外部に公開してしまうと値の書き換えが自由にできてしまう。それを防ぐためにsubjectをprivateにしてObservableを外部に公開する。
class Some {
    private let someSubject = PublishSubject<String>()  //Subjectはprivate

    var observable: Observable<String> { return someSubject } //Observableはpublic
    func sendString(str: String) {
        someSubject.onNext(str) //Subjectでイベントを流す
    }
}