[RxSwift] Subject

·2024년 4월 6일

RxSwift

목록 보기
4/4

Subject

기존에 배운 개념을 생각하면 원래는 Observable은 emit, Observer은 이벤트를 처리하는 역할만 할 수 있다.
그러나, Observable과 Observer의 역할을 동시에 할 수 있어야 하는 케이스가 있다. 이런 경우에 Subject가 사용된다.
예를 들면, 슬라이더로 텍스트의 크기를 조절하는 UI가 있다. 사용자가 슬라이더를 움직이면, 슬라이더의 값이 BehaviorSubject를 통해 방출되고, 이 값을 구독하고 있는 텍스트 레이블이 적절히 반응하여 폰트 크기를 업데이트 해야 한다.

여태까지는 어떤 항목을 방출할 건지 미리 정해두고 observable을 만들었다. 이걸 Cold Observable이라고 하는데, Subject는 이와 다른 Hot Observable이다.
Hot Observable은 어떤 항목을 방출할 것인지에 대한 정의가 없고 원하는 시점마다 항목을 방출한다. 또 하나의 차이점은, observable은 구독들에 대한 observable이 독자적(unicast)인데, subject는 하나의 observable 실행이 여러 subscribe에게 공유(multicast)된다는 점이다.

참고로, UI에 더 적합한 형태로 Relay가 있기도 하다. Relay는 Subject를 내부에서 Wrapping한 형태이다.

Subject의 종류

  • PublishSubject
  • BehaviorSubject
  • RelaySubject
  • AsyncSubject

PublishSubject

PublishSubject는 초기값이 없는 빈 상태로 시작한다.
subscribe 이전에 emit된 애들은 무시한다.

let subject = PublishSubject<String>()

publish.onNext(1)	// 얘는 무시된다

subject
	.subscribe { value in
        print(value)
    } onError: { _ in
        print("error")
    } onCompleted: {
        print("onCompleted")
    } onDisposed:
    	print("Disposed")
    }
    .disposed(by: DisposeBag())
    
publish.onNext(2)
publish.onNext(3)

/*
출력값:
2
3
onCompleted
Disposed
*/

BehaviorSubject

초기값이 있는 상태로 시작한다.(초기값 필수)
subscribe 이전에 emit한 이벤트가 있으면 가장 최근에 전달된 이벤트 하나를 전달받을 수 있다.
만약, subscribe 이전에 emit한 이벤트가 없으면 초기값을 전달한다.

let subject = BehaviorSubject(value: 100)

subject.onNext(1)
subject.onNext(2)

subject
	.subscribe { value in
        print(value)
    } onError: { _ in
        print("error")
    } onCompleted: {
        print("onCompleted")
    } onDisposed:
    	print("Disposed")
    }
    .disposed(by: DisposeBag())

subject.onNext(3)
subject.onNext(4)
subject.onNext(5)

/*
출력값:
2
3
4
5
onCompleted
Disposed
*/

1개의 댓글

와 감사합니다~~ 오늘 적용시켜볼게요!!!!!!!

답글 달기