[iOS] RxSwift(4) - Subject의 등장 Hot & Cold Observable? (v.2.1)

Madeline👩🏻‍💻·2024년 4월 2일

RxSwift study

목록 보기
1/6
post-thumbnail

Subject

Observable과 Observer의 역할을 동시에 수행하는 클래스!

그래서 데이터의 생성과 구독을 함께 관리할 수 있다.

Observable에서는 이벤트를 생성하고, Observer는 그 이벤트를 구독해서 데이터를 다루지 않았나?!

Subject는 이 둘을 합해서 동작한다.

Subject의 종류

  • PublishSubject: 새로운 이벤트를 생성하고, 즉시 구독자에게 전달!
  • BehaviorSubject: 초기값도 있고, 구독하기 전 마지막 이벤트도 있음. 구독하는 순간 그거 전달! 이후에는 새로운 값이 발생할때마다 구독자에게 전달!
  • ReplaySubject: 구독하기 전 발생한 모든 이벤트 전달
  • AsyncSubject: Complete 이벤트가 발생하기 전 마지막으로 발생한 이벤트만 전달(완료 이벤트가 발생한 후에만 최종 이벤트가 전달됨)

PublishSubject

  • 새로운 이벤트를 생성하고, 즉시 이벤트를 전달한다. (==새로운 이벤트만을 전달한다)
import RxSwift

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.onNext("Event 1")

subject.subscribe(onNext: { event in
	print("👩🏻‍🔧구독자1이 \(event) 받음")
}).disposed(by: disposeBag)

subject.onNext("Event 2")

subject.subscribe(onNext: { event in
	print("🧑🏻‍🔧구독자2가 \(event) 받음")
}).disposed(by: disposeBag)

subject.onNext("Event 3")

출력:
👩🏻‍🔧구독자1이 Event 2 받음
👩🏻‍🔧구독자1이 Event 3 받음
🧑🏻‍🔧구독자2가 Event 3 받음

=> 구독하는 시점부터, 새로운 이벤트만 즉시 전달받는다.

언제 써?

빠르개 변화하는 데이터 스트림에서 가장 최신의 데이터만 필요할 때 사용함
ex) 실시간 사용자 입력을 처리할 때

BehaviorSubject

  • Subscribe(연결)하기 직전 값을 갖고 있거나, 초기값을 갖고 있다.
  • 구독하기 시작하면, 초기값이 전달되고, 이후에는 새로운 값이 발생할 때마다 전달된다.
import RxSwift

let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "이것은 초기값")

subject.subscribe(onNext: { event in
	print("👩🏻‍🔧구독자1이 \(event) 받음")
}).disposed(by: disposeBag)

subject.onNext("Event 1")

subject.subscribe(onNext: { event in
	print("🧑🏻‍🔧구독자2가 \(event) 받음")
}).disposed(by: disposeBag)

subject.onNext("Event 2")

출력:
👩🏻‍🔧구독자1이 이것은 초기값 받음
👩🏻‍🔧구독자1이 Event 1 받음
🧑🏻‍🔧구독자2가 Event 1 받음
👩🏻‍🔧구독자1이 Event 2 받음
🧑🏻‍🔧구독자2가 Event 2 받음

=> 구독하는 시점에 초기값(or 직전값)을 전달받고, 그 이후에는 새로운 이벤트를 전달받는다!

언제 써?

초기값을 설정하고, 이후 변화하는 데이터에 대한 구독을 관리할 때 사용
ex) 앱의 상태 관리에서 초기값 유지하고, 그 이후 변화에 대응할 때

RelaySubject

  • 구독하기 전 발생한 모든 이벤트를 전달

  • 중요한 이벤트 로그나 캐시된 데이터를 구독자에게 전달해야 할 때 사용
    ex) 오류 로그, 앱 내에 캐시된 데이터 처리

AsyncSubject

  • 이벤트 발생 전 마지막으로 발생한 이벤트만 전달

  • 어떤 작업의 마지막 결과만 관심이 있는 경우에 사용함
    ex) 비동기 작업의 완료 시점에 결과를 처리할 때

차갑고 뜨거운 Observable?

RxSwift에서 Subject는 Hot Observable의 한 종류이다.

1. 🥶 Cold Observable

  • 구독을 시작하면, 그때서야 데이터를 보내는 Observable
  • 각 구독자는 처음부터 데이터를 받는다.

집에서 영화를 본다고 생각하면 된다. 언제 재생하든 처음부터 시작한다.

종류: just, from, create, deferred, range, interval, timer

2. 🥵 Hot Observable

  • 구독하기 전부터 이미 데이터를 보내고 있는 Observable
  • 구독 시점에 따라 각 구독자가 받는 데이터가 다르다.

이번에는 집에서 TV 생방송을 보고 있다고 생각해보자. 언제 재생하든 현재 방송 중인 내용부터 볼 수 있다.

종류: PublishSubject, BehaviorSubject, ReplaySubject, AsyncSubject, ConnectableObservable

왜 알아야 하나?

  1. 데이터 스트림의 특성을 이해할 수 있다. 데이터가 언제부터 방출되는 지 예측할 수 있다!

  2. 구독 시점에 따라 데이터를 받는 구독자 입장에서 차이가 있지 않나? 수신하는 데이터에 따른 앱의 성능 및 효율성에 대한 차이가 있겠다.

🥵 Hot Observable생방송! 구독 시점에 따라 다른 데이터를 받을 수 있다. 요녀석은 실시간 데이터를 처리할 때 중요하겠다.
예를 들어, 실시간 주식 가격이나, 센서 데이터는 뜨거운 생방송으로 처리해야 실시간 업데이트를 받을 수 있다.

또 얘는 이미 발생한 데이터를 공유하므로, 구독자가 많을 때 더 효율적일 수 있다.

🥶 Cold Observable영화! 구독자마자 새로운 데이터를 생성하므로, 데이터 생성 비용이 클 경우, 비효율적일 수 있다.

사용 예시

  1. API 호출

ex) 유저 프로필 정보를 여러 번 가져와야 할 때, 파일 내용을 여러 번 읽어야 할 때

  • 매번 구독할때마다 새로운 API 호출이 발생해야 한다. => Cold Observable로 각 구독자가 동일한 데이터 세트를 처음부터 받을 수 있다.
  1. 실시간 채팅

ex) 채팅 앱에서 새로운 메시지가 올 때마다 모든 구독자가 실시간으로 메시지를 받아야 할 때

  • 새로운 메시지가 발생할 때, 모든 구독자가 동시에 그 메시지를 받아야 한다. => Hot Observable은 실시간 데이터를 공유한다.

특히 나의 경우 BLE 로봇과 블루투스 통신을 해야 하는 상황에서 Hot Observable을 사용하는 게 좋겠다!!

profile
🍎 Apple Developer Academy@POSTECH 2기, 🍀 SeSAC iOS 4기

0개의 댓글