В чем разница между Signal и Driver в RxSwift?

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

Ответ

Signal и Driver — это специальные «трайты» (traits) в RxSwift, обертки над Observable, предназначенные для упрощения и безопасной работы с UI в основном потоке. Их главное отличие — в поведении при повторной подписке.

Общие черты:

  • Не генерируют ошиб (error). Преобразуются через asSignal(onErrorJustReturn:) или asDriver(onErrorJustReturn:).
  • Работают на главной очереди (MainScheduler.instance). Гарантируют, что события придут в UI-потоке.
  • «Шарятся» (share). Предотвращают повторное выполнение side effects при множественных подписках.

Ключевое различие: Режим «шаринга»

  • Driver использует share(replay: 1, scope: .whileConnected).

    • Что это значит: При новой подписке новый подписчик сразу получит последнее испущенное значение (если оно было).
    • Когда использовать: Для привязки состояния (state) UI. Например, текст лейбла, который должен всегда отображать актуальное значение, даже если подписка произошла позже.
      
      let searchText: Driver<String> = searchTextField.rx.text.orEmpty
      .asDriver()
      .debounce(.milliseconds(300))

    // Подписываем лейбл - он получит текущий текст поля searchText.drive(resultsLabel.rx.text)

  • Signal использует share(scope: .whileConnected) (без replay: 1).

    • Что это значит: При новой подписке новый подписчик НЕ получит последнее значение. Он начнет получать события только с момента подписки.
    • Когда использовать: Для привязки событий (events) UI. Например, нажатия кнопки, где не нужно реагировать на прошлые клики.
      
      let tapSignal: Signal<Void> = button.rx.tap.asSignal()

    // Подписываемся на нажатия. Старые тапы не будут повторно отправлены. tapSignal.emit(onNext: { print("Button tapped") })

Правило выбора:

  • Используй Driver для данных, которые представляют состояние (текст, включен/выключен, массив элементов).
  • Используй Signal для данных, которые представляют события (тапы, жесты, уведомления).