Что такое Hot и Cold Observable в реактивном программировании?

«Что такое Hot и Cold Observable в реактивном программировании?» — вопрос из категории Реактивное программирование, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Hot и Cold — это две категории Observable, определяющие, когда начинается генерация событий и как они распределяются между подписчиками.

Cold Observable

  • Начало выполнения: Генерация данных начинается при каждой новой подписке.
  • Распределение данных: Каждый подписчик получает полную, независимую последовательность данных.
  • Аналогия: Загрузка видео по запросу (YouTube). Каждый зритель запускает свой стрим с начала.
  • Примеры: Результат сетевого запроса, чтение файла, последовательность из массива.
// Пример Cold Observable (RxSwift)
let coldObservable = Observable<String>.create { observer in
    print("Начало сетевого запроса") // Выполнится для КАЖДОГО подписчика
    observer.onNext("Данные 1")
    observer.onNext("Данные 2")
    observer.onCompleted()
    return Disposables.create()
}

coldObservable.subscribe(onNext: { print("Подписчик 1: ($0)") })
coldObservable.subscribe(onNext: { print("Подписчик 2: ($0)") })
// Вывод: Запрос выполнится дважды.

Hot Observable

  • Начало выполнения: Генерация данных начинается независимо от подписок.
  • Распределение данных: Все подписчики получают данные, излучаемые после момента их подписки (общая лента событий).
  • Аналогия: Телевизионная трансляция. Зрители видят то, что идет в эфире с момента включения.
  • Примеры: События UI (нажатия кнопок), обновления местоположения, общие состояния (Subject, Relay).
// Пример Hot Observable (PublishSubject в RxSwift)
let hotObservable = PublishSubject<String>()

hotObservable.onNext("Событие 1") // Еще нет подписчиков, событие потеряно

hotObservable.subscribe(onNext: { print("Подписчик A: ($0)") })

hotObservable.onNext("Событие 2") // Получит только Подписчик A
hotObservable.onNext("Событие 3") // Получит только Подписчик A

hotObservable.subscribe(onNext: { print("Подписчик B: ($0)") })

hotObservable.onNext("Событие 4") // Получат оба подписчика (A и B)

Вывод: Выбор зависит от сценария. Используйте Cold для независимых, повторяемых операций (запросы). Используйте Hot для широковещательных, живых событий (состояние приложения, жесты).