multicast, connect, replay, publish
* 이 포스트는 RxSwift 4.3.1, swift 4.2 버전을 기준으로 작성되었습니다.
Cold Observable 은 subscribe 시점부터 Observable 이 이벤트를 발생시키기 시작한다.
두번의 subscribe 가 일어나면 두개의 이벤트 스트림이 발생한다는 것이다.
하나의 이벤트 스트림을 두개의 subscribe에서 공유하고 싶다면 어떻게 해야할까?
subscriptions 공유 관련 메서드들을 알아보자.
먼저 공유하지 않을때의 이벤트 흐름을 살펴보자.
예제
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: { item in
print("first subscription \(item)")
}).disposed(by: disposeBag)
timer.delaySubscription(2, scheduler: MainScheduler.instance).subscribe(onNext: { item in
print("second subscription \(item)")
}).disposed(by: disposeBag)
아래 결과와 같이 Observable 두개가 서로 각각 이벤트가 발생하는 것을 볼 수 있다.
결과
first subscription 0
first subscription 1
first subscription 2
second subscription 0
first subscription 3
second subscription 1
first subscription 4
second subscription 2
first subscription 5
Observable 의 시퀀스를 하나의 subject 를 통해 multicast 로 이벤트를 전달 하게 된다.
예제
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let subject = PublishSubject<Int>()
let multicast = timer.multicast(subject)
_ = multicast.connect()
multicast.subscribe(onNext: { item in
print("first subscription \(item)")
}).disposed(by: disposeBag)
multicast.delaySubscription(2, scheduler: MainScheduler.instance)
.subscribe(onNext: { item in
print("second subscription \(item)")
}).disposed(by: disposeBag)
* multicast Observable을 connect() 를 하기 전에는 시퀀스가 시작되지 않는다.
결과
first subscription 0
first subscription 1
first subscription 2
second subscription 2
first subscription 3
second subscription 3
second subscribe 시점부터 이벤트가 공유된 것을 확인 할 수 있다.
publish = multicast + publish subject
publish 메서드는 위와 같은 과정을 하나의 메서드로 함축시켜준다.
let publish = Observable<Int>.interval(1, scheduler: MainScheduler.instance).publish()
subscriptions 을 공유시 지정한 버퍼 크기만큼 이벤트를 저장하고 전달해준다.
예제
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let replay = timer.replay(2)
_ = replay.connect()
replay.subscribe(onNext: { item in
print("first subscription \(item)")
}).disposed(by: disposeBag)
replay.delaySubscription(3, scheduler: MainScheduler.instance).subscribe(onNext: { item in
print("second subscription \(item)")
}).disposed(by: disposeBag)
결과
first subscription 0
first subscription 1
first subscription 2
second subscription 1
second subscription 2
first subscription 3
버퍼로 지정한 크기 2만큼 저장되어 이벤트가 공유된 것을 확인 할 수있다.
replayAll 메서드는 모든 이벤트를 저장한다.
메모리나 성능상 이슈가 있을수 있으므로 주의하자.
간단하게 공유를 만들수 있다. subscribe가 더이상 없을때 까지 지속되고 계속 적으로 subscription 을 공유할 수 있다.
shareReplay 는 replay 와 마찬가지로 버퍼를 지정할 수 있다.
shareReplayLatestWhileConnected 는 마지막 버퍼를 공유한다.
let share = Observable<Int>.interval(1, scheduler: MainScheduler.instance).share()
여기까지 subscription 의 공유에 대해서 알아보았다.
이미지 출처: https://medium.com/@_achou/rxswift-share-vs-replay-vs-sharereplay-bea99ac42168
다음에는 driver 와 variable 등에 대해서 알아보자.