새소식

iOS/RxSwift

[RxSwift] Subject

  • -

Subject


observer(관찰자)와 Observable을 모두 수행할 수 있는 Class

※ 여기서 observer은 세부 정보를 저장, 코드를 한 번만 실행하고 모든 observer에 결과를 제공

 

PublishSubject


- 빈 상태로 시작, 새로운 값만 subscriber에 방출

- Observable이 오류로 종료되면 PublishSubject 이후 subscriber에 가지 않고 Observable의 오류로 방출

 

PublishSubject

let publishSubject = PublishSubject<String>()

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

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

publishSubject.onNext("2. 들리세요?")
publishSubject.on(.next("3. 안들리시나요?")) // 위 문장과 동일한 표현

// 첫 번째 구독자 : 2. 들리세요?
// 첫 번째 구독자 : 3. 안들리시나요?

구독자1.dispose()

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

publishSubject.onNext("4. 여보세요")
publishSubject.onCompleted()

publishSubject.onNext("5. 끝났나요?")   // 출력 안됨

구독자2.dispose()

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

publishSubject.onNext("6. 찍힐까요?")   // 출력 안됨


// 첫 번째 구독자 : 2. 들리세요?
// 첫 번째 구독자 : 3. 안들리시나요?
// 두 번째 구독자 : 4. 여보세요
// 세 번째 구독 : completed

 

BehaviorSubject


- 하나의 초깃값을 가진 상태로 시작, 새로운 subscriber에게 초기값 또는 최신값을 방출

- Observable에서 가장 최근에 방출된 항목( 없는 경우 기본값)을 방출하는 것으로 시작하고
나중에 Observable에서 방출한 다른 항목을 계속해서 방출

 

 BehaviorSubject

enum SubjectError: Error{
    case error1
}

let behaviorSubject = BehaviorSubject<String>(value: "초기값")

behaviorSubject.onNext("1. 첫번째값")

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

//behaviorSubject.onError(SubjectError.error1)

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

// 첫번째 구독 : 1. 첫번째값
// 두번쨰 구독 : 1. 첫번째값

let value = try? behaviorSubject.value()
print(value) //  1. 첫번째값

 

ReplaySubject


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

 

ReplaySubject

let replaySubject = ReplaySubject<String>.create(bufferSize: 3)
replaySubject.onNext("1. 여러분")
replaySubject.onNext("2. 힘내세요")
replaySubject.onNext("3. 어렵지만")

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

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

// 두번째 구독 error(error1)

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

replaySubject.subscribe{
    print("세번째 구독", $0.element ?? $0)
}
.disposed(by: disposeBag)
// 세번째 구독 error(Object `RxSwift.(unknown context at $106c44e50).ReplayMany<Swift.String>` was already disposed.)

출처

패스트캠퍼스 | 30개 프로젝트로 배우는 iOS 앱개발 with Swift 초격차 패키지 Online

 

ReactiveX - Subject

If you have a Subject and you want to pass it along to some other agent without exposing its Subscriber interface, you can mask it by calling its asObservable method, which will return the Subject as a pure Observable. See Also

reactivex.io

 

728x90

'iOS > RxSwift' 카테고리의 다른 글

[RxSwift] TimeBasedOperator  (0) 2023.10.03
[RxSwift] Combine Operator  (0) 2023.10.03
[RxSwift] Traits  (0) 2023.09.18
[RxSwift] Observable  (0) 2023.09.10
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.