iOS/RxSwift

Subject의 종류

돼우 2024. 6. 4. 21:15
반응형

Subject의 종류

Subject에 대해 찾아보니 Subject에는 대표적으로 PublishSubject, BehaviorSubject, ReplaySubject가 있고

블로그마다 Variable 혹은 AsyncSubject를 추가로 설명한다.

하나하나 천천히 알아보도록 하자


PublishSubject

빈 값으로 시작하고 새로운 값을 전달 받을 때에 subscriber를 통해 방출

구독 이후에 방출된 이벤트만 observer에게 전달

구독된 순간 새로운 이벤트 수신을 알리고 싶을 때 사용

let publishSubject = PublishSubject<String>()

publishSubject.onNext("0")

publishSubject.subscribe(onNext: {
	print("첫번째 Observer가 받은 항목 : \($0)")
}).disposed(by: disposeBag)

publishSubject.onNext("1")
publishSubject.onNext("2")

publishSubject.subscribe(onNext: {
	print("두번째 Observer가 받은 항목 : \($0)")
}).disposed(by: disposeBag)

publishSubject.onNext("3")
첫번째 Observer가 받은 항목 : 1
첫번째 Observer가 받은 항목 : 2
첫번째 Observer가 받은 항목 : 3
두번째 Observer가 받은 항목 : 3

 

구독 하기 전이 0은 출력되지 않는다.


BehaviorSubject

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

 

주로 뷰를 가장 최신의 데이터로 미리 세팅할 때 사용된다.

(초기값을 스켈레톤 이미지로 설정하고 바인딩 할때 유용할것 같다.)

let behaviorSubject = BehaviorSubject<Int>(value: 1)

behaviorSubject.subscribe(onNext: {
	print("첫번째 Observer가 받는 항목: \($0)")
}).disposed(by: disposeBag)

behaviorSubject.onNext(2)
behaviorSubject.onNext(3)

behaviorSubject.subscribe(onNext: {
	print("두번째 Observer가 받는 항목: \($0)")
}).disposed(by: disposeBag)
첫번째 Observer가 받는 항목: 1
첫번째 Observer가 받는 항목: 2
첫번째 Observer가 받는 항목: 3
두번째 Observer가 받는 항목: 3

첫번째 Observer가 구독했을 때엔 전에 방출한 이벤트가 없어 초기값인 1이 방출되고

두번째 Observer가 구독했을 때엔 가장 최신 이벤트인 3이 있어 3이 방출되는 모습이다.


ReplaySubject

하나 이상의 새로운 이벤트를 버퍼에 저장하고 Observer가 구독을 시작하면 버퍼에 있는 모든 이벤트를 전달한다.

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

내가 받고싶은 만큼의 버퍼 사이즈를 지정해서 구독 할 때 받을 수 있다.

let replaySubject = ReplaySubject<Int>.create(bufferSize: 3)

replaySubject.subscribe(onNext: {
	print("첫번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)


replaySubject.onNext(1)
replaySubject.onNext(2)
replaySubject.onNext(3)
replaySubject.onNext(4)

replaySubject.subscribe(onNext: {
	print("두번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)
첫번째 Observer가 받는 항목 : 1
첫번째 Observer가 받는 항목 : 2
첫번째 Observer가 받는 항목 : 3
첫번째 Observer가 받는 항목 : 4

두번째 Observer가 받는 항목 : 2
두번째 Observer가 받는 항목 : 3
두번째 Observer가 받는 항목 : 4

create 메서드를 이용해서 버퍼 사이즈를 3으로 지정해준다.(가장 최신의 3개의 이벤트를 받음)

처음 구독 시에 전에 방출한 이벤트가 없어 아무런 값도 방출되지 않는다.

두번째의 구독 시엔 전에 방출 했던 4개의 이벤트중 가장 최근의 3개의 이벤트를 방출한다.


AsyncSubject

complete 이벤트가 전달되기 전까지 어떠한 이벤트도 방출하지 않는다.

complete 이벤트가 전달되면, 가장 최근에 전달된 값을 방출한다.

let asyncSubject = AsyncSubject<Int>()

asyncSubject.subscrive(onNext: {
	print("첫번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)

asyncSubject.onNext(1)
asyncSubject.onNext(2)
asyncSubject.onNext(3)

asyncSubject.onCompleted()

 

첫번째 Observer가 받는 항목 : 3

 

구독 한 후에 OnNext로 이벤트를 방출 시켜도 아무런 반응이 없다.

onCompleted 메서드를 호출하면 가장 마지막에 방출된 이벤트를 Observer에게 방출하고 종료한다.


Variable

BehaviorSubject를 래핑하고, 현재의 값을 상태로 보존

complete, error 이벤트가 발생하지 않으며 variable이 해제될 때 자동으로 complete된다.

 

새로운 요소를 추가하기 위해 onNext를 사용 할 수 없음

 

variable은 상태 값이므로 에러가 발생하지 않는 것을 보장하여 error 이벤트를 발생 시킬 수 없음

variable이 해제 될 때 자동으로 complete 되기 때문에 complete 이벤트를 발생 시킬 수 없음

 

현재 값을 확인 하고 싶을 때 사용된다.

let variable = Variable("초기값")

variable.value = "새로운 값"

variable.asObservable().subscribe { (value) in
	print("1) \(value)")
}.disposed(by: disposeBag)

variable.value = "다른 값을 세팅"

variable.asObservable().subscribe { (value) in
	print("2) \(value)")
}.disposed(by: disposeBag)

variable.value = "또 다른 값을 세팅"
1) next(새로운 값)
1) next(다른 값을 세팅)
2) next(다른 값을 세팅)
1) next(또 다른 값을 세팅)
2) next(또 다른 값을 세팅)

참고한 블로그 링크

잘못된 정보나 추가할 정보가 있다면 언제든지 댓글 남겨주세요

반응형

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

Subject에 대해  (0) 2024.04.20
Hot Observable VS Cold Observable  (0) 2024.04.20
Observable, Observer, Subscribe에 대해  (2) 2024.04.08
RxSwift의 기본 개념  (0) 2024.04.07