はじめに
RxSwiftを学習中の初学者です。
RxSwiftを学ぶ上で詰まった点や理解が難しかった点について備忘録と理解の整理のために記事を書いています。
今回の内容
前回は、SubjectとObjectの違いについて書きましたが、今回はSubjectについて深掘りしていきたいと思います。というのも、Subjectにも色々種類があって、どれがどんな機能を持つか訳わからなくなっていたからです。整理のために書いていきます。
Subjectの種類
PublishSubject
RxSwiftのPlaygroundには以下のように書いてありました。
Broadcasts new events to all observers as of their time of the subscription.(購読している時刻の新しいイベントをすべてのオブザーバーにブロードキャストします。)
Subjectには複数オブザーバーを設定できるため、その全てに新しいイベントを通知するということのようです。
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
// 一つ目の観察者登録
subject.subscribe { element in
print(element)
}
subject.onNext("A")
// 二つ目の観察者登録
subject.subscribe { element in
print(element)
}
subject.onNext("B")
実行結果
next(A)
next(B)
next(B)
初めは1つのオブザーバーしか指定していないため、next(A)が一つのみ、
途中でもう一つオブザーバーを追加し、Bを通知するとそれぞれのオブザーバーにnext(B)が通知されます。
BehaviorSubject
Broadcasts new events to all subscribers, and the most recent (or initial) value to new subscribers.(新しいイベントをすべてのサブスクライバーに、最新(または初期)の値を新しいサブスクライバーにブロードキャストします。)
新しいイベントが発生した時、全てのオブザーバーに通知するのはPublishSubjectと同じのようです。
ただし、初期値を設定できるのと、最新の値を新しいオブザーバーに通知する機能があるとのこと。
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "A")
subject.subscribe { element in
print("Observar1:\(element)")
}
subject.onNext("B") // ①
subject.subscribe { element in
print("Observar2:\(element)")
}
subject.onNext("C") // ②
subject.onNext("D") // ③
実行結果
Observar1:next(A)
Observar1:next(B)
Observar2:next(B)
Observar1:next(C)
Observar2:next(C)
Observar1:next(D)
Observar2:next(D)
①が実行された時点では、Observar1にBが通知されますが初期値であるAも通知されています。
②が実行された時点では、Observar2には新しく発生したCしか通知されないはずなのに、Bが通知されています。このように新しく追加されたObservarに対しては、その前に発生したイベントも通知される機能のようです。③の時には新しく発生したイベントだけ通知されているので、オブザーバー追加直後のみですが、
来たばかりの新参者の観察者には一つ前に起こったことを一回だけ教えてあげる優しいやつのようです。
ReplaySubject
Broadcasts new events to all subscribers, and the specified bufferSize number of previous events to new subscribers. (新しいイベントをすべての購読者に、指定されたbufferSize数の前のイベントを新しい購読者にブロードキャストします。)
挙動的には先ほどのBehaviorSubjectに似ていると個人的には思いました。ただBehaviorSubjectのように初期値はないのと、新規のオブザーバーに教える以前のイベントの数を指定できるといった点が違いますが。
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 1)
subject.subscribe { element in
print("Observar1:\(element)")
}
subject.onNext("A")
subject.subscribe { element in
print("Observar2:\(element)")
}
subject.onNext("B")
実行結果
Observar1:next(A)
Observar2:next(A)
Observar1:next(B)
Observar2:next(B)
バッファ数を大きくすれば、新参者の観察者にもその数だけ以前の通知を送ることができるようです。
最後に
今回は、RxSwiftのSubject3種類について書きました。
間違い等あれば教えていただけたら幸いです。
またRxSwiftについて書いていけたらと思います。
最後まで読んでいただきありがとうございました!