SubjectとRelay、そしてTraitsに関してまとめてみました。
RxSwiftを勉強していく中で
Subject、Relay、Signal、Driveといった用語が出てきてその都度検索して理解していたのですが、どれがどれだったのか曖昧になることが多々あり整理した方が良いと思い本記事を書きました📝
Subject
SubjectはObservable且つObserverなものです
= イベントの検知ができる、イベントの発生もできる
イベントとしては
onNext, onError, onComplete
が流れます。
- AsyncSubject
- BehaviorSubject
- PublishSubject
- ReplaySubject
という4つのSubjectがあります。
AsyncSubject
AsyncSubjectのonCompletedが呼ばれた直後に、onNextで渡された最後の値だけが流れます。
![S.AsyncSubject.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F138735%2F8280ca34-5485-2891-3738-00089731f8c3.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=85ab7cec59039c662b75d04c8283c9bc)
最後の値しか必要でない時に、コールバックを受け取る実装をするのに便利です。
(値を受け取るまではロード画面を表示し、値を受け取った場合はダイアログを消し、受け取った値に基づいて特定の処理をする場合など)
BehaviorSubject
初期値をもつSubjectです。
直前に渡された値を保持しsubscribe()された際にその値(初回の場合は初期値)を流します。
onNext,onError, onCompletedは発生次第そのまま流れます。
![S.BehaviorSubject.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F138735%2Fa2f40dda-1329-ac10-15c4-83fce9391f5c.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=b2f04657aac516808c2df67ec557ce47)
PublishSubject
初期値をもたないSubjectです。
onNext,onError, onCompletedは発生次第そのまま流れます。
シンプル。
![S.PublishSubject.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F138735%2Fcd32a7ce-f1a7-e446-abe4-00f67d9f59df.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=456f2a0549570642d35c52157c76ced9)
ReplaySubject
subscribe後に値を流します。
bufferSizeに指定した数だけ値を流します。
![S.ReplaySubject.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F138735%2Feec89b64-b996-59f0-8ebc-975fbb8d26cc.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=76ff01c0a820398165173ec329703b30)
Relay
Subjectのラッパーです。
概要 | イベント | |
---|---|---|
PublishRelay | PublishSubjectのwrapper。初期値なし。 | onNext |
BehaviorRelay | BehaviorSubjectのwrapper。初期値設定可能。 | onNext |
ObservableTypeプロトコルに準拠していますが、Subjectと違いObserverTypeには準拠していません。
また、nextだけが流れ、errorやcompleteは流れません。
イベントは以下のようにして流すことができます。
let somerRelay = BehaviorRelay<String>(value: "")
somerRelay.accept("ABC")
somerRelay.accept("DEF")
Traits
Traitは簡単なObservableのラッパーで、以下のようなものが定義されています。
Rx | Traits |
---|---|
RxCocoa | Driver |
Signal | |
ControlProperty / ControlEvent | |
RxSwift | Single |
Completable | |
Maybe |
RxCocoa traits
Driver
- エラーを流さない
- メインスレッドで実行される
- replay(1) = 直近の値を含めてイベントを流す
(リプレイはその名の通り、同じ物を繰り返す意で捉えるといいと思います)
Signal
- replayしないDriver
その他はDriverと同じで、エラーは流れずメインスレッドで実行されます
ControlProperty / ControlEvent
ControlProperty
- エラーを流さない
- replay(1)
- メモリの割り当てが解放されるとcompleteが流れる
- メインスレッドで実行される
ControlEvent
- エラーを流さない
- 購読時に初期値をながさない
- メモリの割り当てが解放されるとcompleteが流れる
- メインスレッドで実行される
RxSwift traits
Single
名前の通り単一の要素を流す場合に用います。
- 1つの値かエラーを流す
一般的な使用例としては、レスポンスまたはエラー情報を返すHTTPリクエストがあります。永続的なストリームを必要とせず、単一の要素だけを扱う場合はSingleを使えます。
Completable
completeかerrorイベントを流します。
要素は流れません。
- 要素を流さない
- completeかerrorイベントを流す
Maybe
SingleとCompletableを組み合わせたようなものです。
- completeか単一の値、もしくはエラーが流れます
ストリームに値を流したいが、必ずしもそれが必要でない場合はMaybeが使えます。