Ответ
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для данных, которые представляют события (тапы, жесты, уведомления).