RxSwift - 3. Subject

박성민·2021년 4월 6일
0

RxSwift

목록 보기
3/4

Subject

Observer인 동시에 Observable
Subject로 전달되는 이벤트를 Observer로 전달하는 가장 기본적인 Subject이다. 즉 이벤트를 전달하는 역할과 이벤트를 전달받는 역할 모두를 할 수 있습니다.

Subject의 종류

PublishSubject

Element없이 빈 상태로 생성되고, subscriber는 subscribe한 시점 이후에 발생되는 이벤트만 전달받습니다.

let subject = PublishSubject<String>()
subject.onNext("hello?")

위의 코드를 수행해도 아무일도 일어나지 않습니다. 구독자(subscriber)가 없기 때문입니다.

let subscriber = subject
    .subscribe(onNext: { str in
        print(str)
    })

subscribe 하는 코드를 넣어도 마찬가지로 print문이 실행되지 않습니다.
그 아래 코드를 추가하면

subject.onNext("Hi")

이번엔 print문이 실행될 것입니다.

PublishSubject는 시간의 흐름과 관련된 모델에 적합합니다.

어떤 스트리밍 사이트를 예를 들어보면 12시에 방송이 종료되기 때문에, 9시 59분에 '1분 뒤 방송이 종료됩니다.'라는 알림을 준다고 할 때, 10시 1분에 접속한 사용자는 이 정보를 알 필요가 없다.

이미 지나간 알림이 필요할 경우에는 BehaviorSubject를 사용하면 됩니다.

BehaviorSubject

PublishSubject와 유사합니다. 차이점은 반드시 초기 값을 가지고 생성됩니다. subscribe가 발생하면, 발생한 시점 이전에 발생한 이벤트 중 가장 최신의 이벤트를 전달받습다.

위에서 본 Publish Subject와 상당히 유사하지만, Subscriber가 발생하면 바로 최근에 발생한 이벤트 하나를 emit합니다.

let disposeBag = DisposeBag()

enum MyError: Error {
   case error
}

let b = BehaviorSubject<Int>(value: 0)
b.subscribe { print("BehaviorSubject >>", $0) }
    .disposed(by: disposeBag)

b.onNext(1)
b.subscribe { print("BehaviorSubject2 >>", $0) }
    .disposed(by: disposeBag)
    
b.onError(MyError.error)
b.subscribe { print("BehaviorSubject3 >>", $0) }
    .disposed(by: disposeBag)


처음으로 behaviorSubject를 구독하면 바로 기본값인 0을 방출합니다.
1을 방출하고 새로운 구독자가 발생하면 가장 최근 방출값인 1을 같이 받습니다.
error이후에 구독을 하면 같이 error메시지를 받습니다.

ReplaySubject

BufferSize와 함께 생성됩니다. BehaviorSubject와 유사하지만, BufferSize만큼의 최신 이벤트를 전달받습다.

let disposeBag = DisposeBag()

enum MyError: Error {
   case error
}

let rs = ReplaySubject<Int>.create(bufferSize: 3)
(1...10).forEach { rs.onNext($0) }
rs.subscribe{ print("Observer 1 >>", $0) }
    .disposed(by: disposeBag)
rs.subscribe{ print("Observer 2 >>", $0) }
    .disposed(by: disposeBag)
rs.onNext(11)

rs.subscribe{ print("Observer 3 >>", $0) }
    .disposed(by: disposeBag)
rs.onError(MyError.error)
rs.subscribe{ print("Observer 4 >>", $0) }
    .disposed(by: disposeBag)

참고 및 출처

http://reactivex.io/documentation/subject.html
https://yeonduing.tistory.com/61
https://rhammer.tistory.com/289

profile
iOS시작~

0개의 댓글