iOS/RxSwift

[RxSwift] Subject - PublishSubject

_Rey 2022. 9. 14. 16:53

Observable은 다른 Observable를 Subscribe하지 못하고, Observer는 다른 Observer로 이벤트를 전달하지 못한다.

Subject는 다른 Observable로 부터 이벤트를 받아서 Subscriber로 전달할 수 있다. Observable인 동시에 Observer인 셈이다.

Subject의 종류

  • PublishSubject: Subject로 전달되는 새로운 이벤트를 Subscriber로 전달한다.
  • BehaviorSubject: 생성시점에 시작 이벤트를 지정하고, Subject로 전달되는 이벤트 중에 가장 마지막에 전달된 최신 이벤트를 저장해두었다가 새로운 Subject에게 최신 이벤트를 전달한다.
  • ReplaySubject: 하나 이상의 최신 이벤트를 버퍼에 저장한다. Observer가 Subscribe을 시작하면 버퍼의 모든 이벤트를 전달한다.
  • AsyncSubject: Subject로 Completed가 전달되는 시점에 마지막으로 전달된 Next 이벤트를 Subscriber로 전달한다.

PublishSubject부터 하나씩 알아보자.

 

PublishSubject

let publishSubject = PublishSubject<String>()
// String Next 이벤트를 다른 Observer에게 전달

전달되는 이벤트를 Observer에게 전달하는 가장 기본적인 Subject이다.

 

publishSubject.onNext("Hello")

let _ = publishSubject.subscribe {
        print("1", $0)
    }
    .disposed(by: disposeBag)

publishSubject.onNext("World")

// Output
1 next(World)

.onNext("Hello") 이벤트는 Observer가 Subscribe하기 전의 이벤트이기 때문에 호출되지 않는다.

 

https://reactivex.io/documentation/subject.html

PublishSubject는 구독 이후에 배출된 이벤트만 배출한다.

 

let _ = publishSubject.subscribe {
         print("2", $0)
    }
    .disposed(by: disposeBag)

publishSubject.onNext("RxSwift")

// Output
1 next(RxSwift)
2 next(RxSwift)

기존에 Subscribe한 Observer와 새로운 Observer 모두 .onNext("RxSwift") 이벤트를 받아 호출했다.

 

publishSubject.onCompleted()

let _ = publishSubject.subscribe {
    print("3", $0)
}
.disposed(by: disposeBag)

//Output
1 completed
2 completed
3 completed

이미 Completed 또는 Error 이벤트가 호출된 Subject에 대해서는

새롭게 Subscribe 했을때 바로 Completed 또는 Error 이벤트가 호출된다.

https://reactivex.io/documentation/subject.html

 

번외 Obverser의 분리

let observer: (Event<String>) -> Void = {
    print("4", $0)
}

publishSubject
    .subscribe(observer)
    .disposed(by: disposeBag)

//Output
4 completed