iOS/RxSwift

[RxSwift] Subject 알아보기

728x90

PublishSubject

: 빈 상태로 시작하여 새로운 값만을 subscriber에 방출한다.

✨ 구독하기 전에 일어난 이벤트는 반영되지 않는다.

BehaviorSubject

: 하나의 초기값을 가진 상태로 시작하여, 새로운 subscriber에게 초기값 또는 최신값을 방출한다.

✨ 구독하기 직전에 일어난 이벤트는 반영된다.

ReplaySubject

: 버퍼를 두고 초기화하며, 버퍼 사이즈 만큼의 값들을 유지하면서 새로운 subscriber에게 방출한다.

✨ 지나간 이벤트여도 버퍼 사이즈 만큼 남겨둔다.

 

소스 코드

import RxSwift

let disiposeBag = DisposeBag()

//📌 PublishSubject
print("----PublishSubject----")
let publishSubject = PublishSubject<String>()

publishSubject.onNext("1. 여러분 안녕하세요")

let 구독자1 = publishSubject
    .subscribe(onNext:{
        print("첫번째 구독:", $0)
    })

publishSubject.onNext("2. 들리세요?")
publishSubject.onNext("3. 안들리시나요?")

구독자1.dispose()

let 구독자2 = publishSubject
    .subscribe(onNext:{
        print("두번째 구독:", $0)
    })

publishSubject.onNext("4. 여보세요")
publishSubject.onCompleted()
//✨ onCompleted 이후 이벤트는 방출되지 않는다.
publishSubject.onNext("5. 끝났나요")

구독자2.dispose()

publishSubject
    .subscribe{
        print("세번째 구독:", $0.element ?? $0)
    }
    .disposed(by: disiposeBag)

publishSubject.onNext("6. 찍할까요?")

//📌 BehaviorSubject
print("----BehaviorSubject----")
enum SubjectError: Error{
    case error1
}

let behaviorSubject = BehaviorSubject<String>(value: "0. 초기값")
behaviorSubject.onNext("1. 첫번째값")

behaviorSubject.subscribe{
    print("첫번째 구독:", $0.element ?? $0)
}
.disposed(by: disiposeBag)

//publishSubject.onError(SubjectError.error1)

behaviorSubject.subscribe{
    print("두번째 구독:", $0.element ?? $0)
}
.disposed(by: disiposeBag)

//✨ .value()로 값 확인 가능
let value = try? behaviorSubject.value()
print(value)

//📌 ReplaySubject
print("----ReplaySubject----")
let replaySubject = ReplaySubject<String>.create(bufferSize: 2)

replaySubject.onNext("1. 여러분")
replaySubject.onNext("2. 힘내세요")
replaySubject.onNext("3. 어렵지만")

replaySubject.subscribe{
    print("첫번째 구독:", $0.element ?? $0)
}
.disposed(by: disiposeBag)

replaySubject.subscribe{
    print("두번째 구독:", $0.element ?? $0)
}
.disposed(by: disiposeBag)

replaySubject.onNext("4. 할 수 있어요.")
replaySubject.onError(SubjectError.error1)
replaySubject.dispose()

replaySubject.subscribe{
    print("세번째 구독:", $0.element ?? $0)
}
.disposed(by: disiposeBag)

 

실행 결과

----PublishSubject----
첫번째 구독: 2. 들리세요?
첫번째 구독: 3. 안들리시나요?
두번째 구독: 4. 여보세요
세번째 구독: completed
----BehaviorSubject----
첫번째 구독: 1. 첫번째값
두번째 구독: 1. 첫번째값
Optional("1. 첫번째값")
----ReplaySubject----
첫번째 구독: 2. 힘내세요
첫번째 구독: 3. 어렵지만
두번째 구독: 2. 힘내세요
두번째 구독: 3. 어렵지만
첫번째 구독: 4. 할 수 있어요.
두번째 구독: 4. 할 수 있어요.
첫번째 구독: error(error1)
두번째 구독: error(error1)
세번째 구독: error(Object `RxSwift.(unknown context at $105d6ee80).ReplayMany<Swift.String>` was already disposed.)
728x90