【RxSwift】Subjectまとめ

PublishSubject

let publishSubject = PublishSubject<Int>()
publishSubject.asObservable().subscribe { (event) in
    print("publishSubject: 1, event:\(event)")
}

publishSubject.onNext(1)
publishSubject.onNext(2)

publishSubject.asObservable().subscribe { (event) in
    print("publishSubject: 2, event:\(event)")
}

publishSubject.onNext(3)
publishSubject.onNext(4)
publishSubject.onCompleted()
// 結果
publishSubject: 1, event:next(1)
publishSubject: 1, event:next(2)
publishSubject: 1, event:next(3)
publishSubject: 2, event:next(3)
publishSubject: 1, event:next(4)
publishSubject: 2, event:next(4)
publishSubject: 1, event:completed
publishSubject: 2, event:completed

ReplaySubject

Subscribeしたタイミングで今の状態から遡って指定数または全て通知する。

let replaySubject = ReplaySubject<Int>.create(bufferSize: 2)

replaySubject.asObservable().subscribe { (event) in
    print("replaySubject: 1, event:\(event)")
}

replaySubject.onNext(1)
replaySubject.onNext(2)
replaySubject.onNext(3)
replaySubject.onNext(4)

replaySubject.asObservable().subscribe { (event) in
    print("replaySubject: 2, event:\(event)")
}

replaySubject.onNext(5)
replaySubject.onNext(6)
replaySubject.onCompleted()
// 結果
replaySubject: 1, event:next(1)
replaySubject: 1, event:next(2)
replaySubject: 1, event:next(3)
replaySubject: 1, event:next(4)
// ※ 2つ目のsubscribeが実行されたタイミングで 指定した値(2)遡って通知する
replaySubject: 2, event:next(3)
replaySubject: 2, event:next(4)
replaySubject: 1, event:next(5)
replaySubject: 2, event:next(5)
replaySubject: 1, event:next(6)
replaySubject: 2, event:next(6)
replaySubject: 1, event:completed
replaySubject: 2, event:completed

BehaviorSubject

今の状態を一回通知した上で変化があった場合それを通知する

let behaviorSubject = BehaviorSubject<Int>(value: 0)

behaviorSubject.asObservable().subscribe { (event) in
    print("behaviorSubject: 1, event:\(event)")
}

behaviorSubject.onNext(1)
behaviorSubject.onNext(2)

behaviorSubject.asObservable().subscribe { (event) in
    print("behaviorSubject: 2, event:\(event)")
}

behaviorSubject.onNext(3)
behaviorSubject.onNext(4)
behaviorSubject.onCompleted()
// 結果
// ※ 1つ目のsubscribeが実行されたタイミングで最後の値(0)が通知される
behaviorSubject: 1, event:next(0)
behaviorSubject: 1, event:next(1)
behaviorSubject: 1, event:next(2)
// ※ 2つ目のsubscribeが実行されたタイミングで最後の値(2)が通知される
behaviorSubject: 2, event:next(2)
behaviorSubject: 1, event:next(3)
behaviorSubject: 2, event:next(3)
behaviorSubject: 1, event:next(4)
behaviorSubject: 2, event:next(4)
behaviorSubject: 1, event:completed
behaviorSubject: 2, event:completed

Variable

BehaviorSubjectのラッパー。Variableは明示的にonCompleted, onErrorになることはない。 解放時に自動的にonCompletedを発行する。
※ RxSwift 4.0.0-rc.0よりdeprecated

let variable = Variable(0)

variable.asObservable().subscribe({ (event) in
    print("variable: 1, event:\(event)")
})

variable.value = 1
variable.value = 2

variable.asObservable().subscribe({ (event) in
    print("variable: 2, event:\(event)")
})

variable.value = 3
variable.value = 4
// 結果
variable: 1, event:next(0)
variable: 1, event:next(1)
variable: 1, event:next(2)
variable: 2, event:next(2)
variable: 1, event:next(3)
variable: 2, event:next(3)
variable: 1, event:next(4)
variable: 2, event:next(4)
// 変数が解放されたタイミングでonCompletedが発行される
variable: 1, event:completed
variable: 2, event:completed

PublishRelay

PublishSubjectのラッパー。onCompleted, onErrorが発行されることがない。

let publishRelay = PublishRelay<Int>()
publishRelay.asObservable().subscribe { (event) in
    print("PublishRelay: 1, event:\(event)")
}

publishRelay.accept(1)
publishRelay.accept(2)

publishRelay.asObservable().subscribe { (event) in
    print("PublishRelay: 2, event:\(event)")
}

publishRelay.accept(3)
publishRelay.accept(4)
// 結果
PublishRelay: 1, event:next(1)
PublishRelay: 1, event:next(2)
PublishRelay: 1, event:next(3)
PublishRelay: 2, event:next(3)
PublishRelay: 1, event:next(4)
PublishRelay: 2, event:next(4)

BehaviorRelay

BehaviorSubjectのラッパー。onCompleted, onErrorが発行されることがない。

let behaviorRelay = BehaviorRelay<Int>(value: 0)
behaviorRelay.asObservable().subscribe { (event) in
    print("behaviorRelay: 1, event:\(event)")
}

behaviorRelay.accept(1)
behaviorRelay.accept(2)

behaviorRelay.asObservable().subscribe { (event) in
    print("behaviorRelay: 2, event:\(event)")
}.disposed(by: disposeBag)

behaviorRelay.accept(3)
behaviorRelay.accept(4)
// 結果
behaviorRelay: 1, event:next(0)
behaviorRelay: 1, event:next(1)
behaviorRelay: 1, event:next(2)
behaviorRelay: 2, event:next(2)
behaviorRelay: 1, event:next(3)
behaviorRelay: 2, event:next(3)
behaviorRelay: 1, event:next(4)
behaviorRelay: 2, event:next(4)

参考