/RxSwift

[RxSwift] “Hot” Observables, “Cold” Observables

아렉스_Arex 2025. 2. 28. 00:32
반응형

 

2025.02.25 - [/RxSwift] - [RxSwift] RxSwift 란 무엇일까 ?

2025.02.26 - [/RxSwift] - [RxSwift] RxSwift를 이루는 Observable과 Observer

 

안녕하세요 아렉스입니다 :>

오늘은 Observable의 종류 두가지, Hot ObservableCold Observable에 대해서 얘기하겠습니다.

 

1. Hot Observable과 Cold Observable이란?


RxSwift에서 Observable은 데이터를 방출하는 방식에 따라 Cold Observable Hot Observable로 나뉩니다. 이 두 가지의 차이를 이해하면, RxSwift에서 데이터를 다루는 방식을 보다 효과적으로 활용할 수 있습니다.

 

2. Cold Observable


Cold Observable 구독(Subscribe)하기 전까지 이벤트를 방출하지 않는 Observable입니다.

즉, 각 구독자(Subscriber)마다 독립적인 데이터 스트림을 받습니다.

특징

  • 구독을 해야만 데이터를 받을 수 있음.
  • 구독할 때마다 새로운 데이터를 생성.
  • 네트워크 요청, 파일 읽기 등의 경우에 적합.

 

예제

import RxSwift

let observable = Observable<Int>.create { observer in
    print("데이터 생성 시작")
    observer.onNext(1)
    observer.onNext(2)
    observer.onNext(3)
    observer.onCompleted()
    return Disposables.create()
}

// ✅ 구독 1
let subscription1 = observable.subscribe(onNext: { value in
    print("구독 1: \(value)")
})

// // ✅ 구독 2
let subscription2 = observable.subscribe(onNext: { value in
    print("구독 2: \(value)")
})

// ✅ 실행결과
// 구독1: red
// 구독1: blue
// 구독1: yellow

// 구독2: red
// 구독2: blue
// 구독2: yellow

 

 

 

3. Hot Observable


Hot Observable 구독 여부와 관계없이 데이터를 지속적으로 방출하는 Observable입니다.

따라서 새로운 구독자 과거 이벤트를 받을 수 없고, 방출되는 시점 이후의 데이터만 수신합니다.

특징

  • 구독 전에 발생한 이벤트는 받을 수 없음.
  • 모든 구독자가 동일한 데이터를 공유.
  • UI 이벤트(Button Tap), 타이머, 센서 데이터 등의 경우에 적합.

예제 (PublishSubject 사용)

import RxSwift

let subject = PublishSubject<String>()

// ✅ 구독1
let subscription1 = subject.subscribe(onNext: { value in
    print("구독 1: \(value)")
})

subject.onNext("A")
subject.onNext("B")

// ✅ 구독2
let subscription2 = subject.subscribe(onNext: { value in
    print("구독 2: \(value)")
})

subject.onNext("C")
subject.onNext("D")

// ✅ 실행결과
// 구독1: A
// 구독1: B
// 구독1: C
// 구독2: C
// 구독1: D
// 구독2: D

 

4. Cold Observable을 Hot Observable로 변환하기


하지만 여러 구독자가 단 하나의 구독의 이벤트(요소)를 공유하도록 하려면 어떻게 해야 할까요 ?

기본적으로 Observable Cold Observable이지만, share()를 사용하면 Hot Observable처럼 동작하도록 만들 수 있습니다.

예제

// ✅ 1초 단위로 이벤트 방출
let interval = Observable<Int>
            .interval(.seconds(1), scheduler: MainScheduler.instance)
            .share(replay: 1)

// ✅ 구독 1
interval
    .subscribe(onNext: { data in
        print("구독: \(data)")
    })
    .disposed(by: self.diposeBag)

// ✅ 구독 2        
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
    interval
        .subscribe(onNext: { data in
            print("구독2: \(data)")
        })
        .disposed(by: self.diposeBag)
})

// ✅ 실행결과
// 구독: 0
// 구독: 1
// 구독: 2
// 구독: 3
// 구독: 4
// 구독2: 4 <-- 구독이 늦어져서 4부터 받음
// 구독:  5
// 구독2: 5
// 구독:  6
// 구독2: 6
// 구독:  7
// 구독2: 7
// 구독:  8
// 구독2: 8

 

 

https://reactivex.io/documentation/ko/observable.html