RxSwift — шта је, могућности и реактивно програмирање

Аутор: IT Sectr Објављено: 2026-05-03 Време читања: 10 мин

RxSwift — это библиотека реактивного программирования для iOS, реализующая паттерн Observable и функциональные операторы для работы с асинхронными потоками данных. Она портирует концепции ReactiveX (Rx) на язык Swift, предоставляя единый API для обработки событий от UI, сетевых запросов, БД и таймеров. По данным ReactiveX, 2025, библиотека используется более чем в 60 000 проектах на GitHub и остаётся стандартом реактивного программирования для Swift до появления нативного Combine. RxSwift заменяет делегаты, замыкания и уведомления единой цепочкой обработки событий.

Главно

  • RxSwift — имплементација ReactiveX за Swift, заснована на обрасцу Observable и ланцима оператора
  • Observable — извор асинхроних догађаја који може да се заврши успешно, грешком или бесконачно
  • Subject — гибрид Observable и Observer, позволяющий вручную отправлять события в поток
  • Schedulers управляют на каком потоке выполняется подписка, наблюдение и обработка событий
  • Операторы map, flatMap, filter, combineLatest трансформируют и комбинируют потоки без состояния гонок

Шта је RxSwift?

RxSwift — это Swift-порт библиотеки ReactiveX (Rx), созданной компанией Microsoft для .NET в 2012 году. Основная идея Rx — представить любой асинхронный источник данных как Observable последовательность, к которой можно применять функциональные операторы. В iOS-разработке RxSwift используется для связывания UI-событий (нажатия кнопок, ввод текста, жесты) с логикой приложения без явных делегатов и target-action.

Библиотека состоит из трёх модулей: RxSwift (ядро — Observable, Operator, Scheduler), RxCocoa (интеграция с UIKit — rx-расширения для UIButton, UITextField, UITableView) и RxRelay (Subject без терминальных событий). Такое разделение позволяет использовать ядро в серверном Swift и тестах, подключая UI-обвязку только для iOS-приложений.

Согласно опросу Stack Overflow, 2025, RxSwift входит в топ-5 наиболее используемых сторонних библиотек для iOS. Основная причина популярности — единообразная обработка всех асинхронных паттернов: сетевые запросы через URLSession, анимации через UIViewPropertyAnimator, уведомления через NotificationCenter и делегаты через DelegateProxy — всё это сводится к Observable с предсказуемым жизненным циклом.

Филозофија реактивног програмирања

Реактивное программирование — это парадигма, в которой программа реагирует на изменения данных, а не опрашивает их. Вместо того чтобы писать «получить данные → обработать → обновить UI», разработчик описывает цепочку трансформаций: «когда данные изменятся, применить фильтр, затем map, затем обновить UI». RxSwift реализует эту парадигму через Observable цепочки с ленивым выполнением — ничего не происходит, пока не появится подписчик.

Кључни компоненте RxSwift: Observable, Subject, Disposable

Observable — фундаментальный тип RxSwift, представляющий последовательность событий во времени. Observable может отправлять три типа событий: next (новое значение), error (ошибка, завершающая поток) и completed (успешное завершение). Существуют finite Observable (завершаются после отправки всех значений) и infinite Observable (например, UI-события — никогда не завершаются).

Observable и његов животни циклус

Жизненный цикл Observable включает три стадии: создание (create, just, from), трансформация (операторы map, filter, flatMap) и подписка (subscribe). Без подписки Observable не выполняет никаких действий — это ленивая последовательность. После подписки Observable начинает отправлять события подписчику до тех пор, пока не завершится или подписчик не отменит подписку через Disposable.

swift
import RxSwift

// Креирање Observable-а из низа
let numbers = Observable.from([1, 2, 3, 4, 5])

// Трансформација кроз операторе
let squared = numbers
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }

// Претплата са обрадом догађаја
let disposable = squared
    .subscribe(onNext: { print($0) },
               onError: { print("Error: \($0)") },
               onCompleted: { print("Done") })

Subject — это тип, который одновременно является Observable (на него можно подписаться) и Observer (в него можно отправлять события). RxSwift предоставляет четыре типа Subject: PublishSubject (только новые события), BehaviorSubject (с начальным значением), ReplaySubject (буферизация последних N событий) и AsyncSubject (только последнее значение перед завершением). Subject удобен для интеграции императивного кода (замыкания, делегаты) в реактивную цепочку.

Disposable — это токен отмены подписки. Когда подписчик больше не хочет получать события, он вызывает disposable.dispose(). На практике используется DisposeBag: коллекция Disposable, которая автоматически отменяет все подписки при деинициализации владельца (например, UIViewController). Это предотвращает утечки памяти, неизбежные при ручном управлении подписками.

Тип SubjectНачальное значениеПовторяет подписчикуИспользование
PublishSubjectНетТолько новые событияUI-события, редкие уведомления
BehaviorSubjectДаПоследнее + новыеСостояние, стрим данных
ReplaySubjectНетБуфер N + новыеКэширование истории
AsyncSubjectНетТолько последнееВычислительные задачи
PublishRelayНетТолько новыеБез error/completed

Оператори трансформације и филтрације токова

Операторы RxSwift — это функции, которые принимают один Observable и возвращают другой Observable, трансформируя поток данных. Комбинируя операторы, разработчик строит декларативные цепочки обработки без промежуточных переменных и состояний гонок. Все операторы ленивы: цепочка строится при описании, а выполняется при подписке.

Операторы трансформации изменяют каждое событие в потоке. map применяет функцию к каждому элементу, flatMap разворачивает Observable от каждого элемента в один плоский поток, scan накапливает промежуточный результат (аналог reduce, но с эмиссией каждого шага). buffer группирует элементы по времени или количеству, window делит поток на вложенные Observable по окнам.

swift
// Пример ланца оператора: претрага са debounce
searchTextField.rx.text
    .orEmpty
    .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
    .distinctUntilChanged()
    .flatMapLatest { query -> Observable<[String]> in
        return apiService.search(query)
    }
    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { _, item, cell in
        cell.textLabel?.text = item
    }
    .disposed(by: disposeBag)

Операторы фильтрации пропускают только те события, которые удовлетворяют условию. filter отсеивает по предикату, distinctUntilChanged пропускает только значения, отличные от предыдущего, take и takeWhile ограничивают количество событий. skip и skipWhile пропускают первые N событий или события до выполнения условия. Для обработки ошибок используются catchError (перехват и подмена) и retry (повтор последовательности при ошибке).

Операторы комбинирования объединяют несколько Observable в один. combineLatest объединяет последние значения из нескольких потоков в кортеж, zip попарно комбинирует элементы с одинаковыми индексами, merge объединяет несколько потоков в один в порядке поступления событий. withLatestFrom комбинирует событие из основного потока с последним значением из другого потока — удобно для UI-событий с текущим состоянием.

КатегорияОператорЧто делает
ТрансформацияmapПреобразует каждое значение через функцию
ТрансформацияflatMapРазворачивает вложенные Observable в плоский поток
ФильтрацияfilterПропускает значения по предикату
ФильтрацияdistinctUntilChangedПропускает только изменившиеся значения
КомбинированиеcombineLatestОбъединяет последние значения из 2+ потоков
КомбинированиеzipПопарно комбинирует элементы по индексу
УправлениеdebounceЗадерживает события до паузы в потоке
УправлениеtakeБерёт первые N событий и завершает поток

Schedulers и управљање нитима извршавања

Scheduler в RxSwift — это абстракция над потоком выполнения (или очередью). Scheduler определяет, на каком потоке выполняется создание событий, трансформация и подписка. В отличие от GCD, где разработчик явно указывает DispatchQueue, RxSwift использует два параметра: subscribeOn (на каком потоке выполняется Observable) и observeOn (на каком потоке вызывается подписчик).

MainScheduler и BackgroundScheduler

MainScheduler выполняет код на главном потоке — обязателен для обновления UIKit (все UI-изменения должны происходить на main thread). SerialDispatchQueueScheduler оборачивает последовательную GCD-очередь, ConcurrentDispatchQueueScheduler — параллельную. Для фоновых задач используется ConcurrentDispatchQueueScheduler с qos: .background или .utility.

swift
// Типичан образац: посадински рад + UI на main
apiService.fetchData()
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { data in
        self.tableView.reloadData()
        self.loadingIndicator.stopAnimating()
    })
    .disposed(by: disposeBag)

Правильное использование Scheduler предотвращает блокировку UI при сетевых запросах и тяжёлых вычислениях. subscribeOn влияет на весь upstream (все операторы до observeOn выполняются на указанном планировщике). observeOn переключает downstream — все операторы после observeOn выполняются на указанном планировщике. В цепочке может быть несколько observeOn для переключения между потоками на разных этапах трансформации.

SerialDispatchQueueScheduler гарантирует последовательную обработку событий, что важно для потокобезопасности общих ресурсов. Для высоконагруженных операций (обработка изображений, парсинг JSON) используйте ConcurrentDispatchQueueScheduler — RxSwift сохранит порядок событий внутри одного Observable, но разные Observable могут обрабатываться параллельно.

Практична примена RxSwift у iOS-у

RxSwift в iOS-проектах чаще всего применяется для связывания UI с данными через реактивные цепочки. RxCocoa предоставляет rx-расширения для всех стандартных UIKit-компонентов: rx.tap для UIButton, rx.text для UITextField, rx.selectedRow для UIPickerView. Это позволяет отказаться от @IBAction и делегатов, заменив их декларативными подписками.

RxSwift у комбинацији са MVVM

MVVM (Model-View-ViewModel) — архитектурный паттерн, в котором ViewModel управляет состоянием и бизнес-логикой, а View подписывается на реактивные свойства ViewModel. RxSwift идеально вписывается в MVVM: ViewModel публикует Observable или Driver для данных, View подписывается на них через bind. ViewModel не имеет ссылки на View — она возвращает Observable, которые View потребляет.

swift
class LoginViewModel {
    let email = BehaviorRelay<String>(value: "")
    let password = BehaviorRelay<String>(value: "")

    var isFormValid: Observable<Bool> {
        return Observable
            .combineLatest(email, password) {
                !$0.isEmpty && $0.contains("@") && $1.count >= 6
            }
    }
}

// У ViewController-у:
viewModel.isFormValid
    .bind(to: loginButton.rx.isEnabled)
    .disposed(by: disposeBag)

Сетевые запросы — вторая по частоте область применения RxSwift. URLSession.rx.response оборачивает HTTP-запрос в Observable, который возвращает (response, data) при успехе или error при неудаче. В комбинации с Codable и оператором map получается компактный реактивный слой API: Observable без callback-ов и обработки ошибок в каждом методе. При ошибке сети оператор retry(3) автоматически повторяет запрос трижды с экспоненциальной задержкой.

RxSwift наспрам Combine

Combine — нативный фреймворк Apple, представленный в iOS 13. Он решает те же задачи, что и RxSwift: работа с асинхронными событиями через Publisher, Subscriber и операторы. Однако Combine имеет ключевые отличия: строгая типизация ошибок через Failure тип, встроенная поддержка Swift Concurrency (async/await) и интеграция с SwiftUI через @Published и ObservableObject.

RxSwift выигрывает в обратной совместимости — он поддерживает iOS 8+, тогда как Combine требует iOS 13+. RxSwift имеет более богатую экосистему сторонних расширений (RxDataSources, RxGesture, RxAnimated) и детальную документацию по операторам. Для проектов с поддержкой старых версий iOS RxSwift остаётся единственным выбором.

Для новых проектов с iOS 13+ Apple рекомендует Combine. Он тесно интегрирован с SwiftUI, имеет меньший размер бинарника и официальную поддержку. Однако миграция существующего RxSwift-кода на Combine требует переписывания всех Observable → Publisher, а экосистема RxCocoa не имеет полного Combine-аналога — UIKit не имеет нативных [Publisher] для всех UI-компонентов.

ХарактеристикаRxSwiftCombine
Минимальная iOSiOS 8+iOS 13+
Тип ошибкиError (любая)Generic Failure
UI-расширенияRxCocoa (UIKit, AppKit)@Published (SwiftUI)
Операторы400+ операторов~100 операторов
Swift ConcurrencyЧерез бриджНативная поддержка
СтатусСторонняяApple официально

Често постављана питања

В чём разница между Observable и Subject в RxSwift?

Observable — источник событий с ленивым выполнением. Subject одновременно является Observable и Observer — вы можете подписаться на него и отправлять в него новые события вручную. Subject удобен для интеграции императивного кода в реактивные цепочки.

Когда использовать RxSwift вместо Combine?

RxSwift выбирают при необходимости поддержки iOS 11-12, при наличии существующей RxSwift-кодовой базы или при потребности в богатой экосистеме операторов (400+ против ~100 в Combine). Для новых проектов на iOS 13+ предпочтителен Combine.

Что такое DisposeBag и зачем он нужен?

DisposeBag — коллекция токенов Disposable, автоматически отменяющая все подписки при деинициализации владельца. Без DisposeBag подписка создаёт strong reference на замыкание, что приводит к утечке памяти при уничтожении UIViewController.

Как обрабатывать ошибки в RxSwift?

Используйте catchError для замены ошибки значением по умолчанию, retry для повторного выполнения Observable, materialize для преобразования ошибки в событие. В UI-слое Driver и Signal не передают ошибки — они обрабатываются внутри.

Чем Driver отличается от Observable в RxCocoa?

Driver — это специальный тип Observable, гарантирующий выполнение на MainScheduler, отсутствие ошибок и sharing ресурсов. Driver гарантирует, что UI-обновления происходят на главном потоке. Observable не даёт таких гарантий — требуется observeOn.

Закључак

  • RxSwift — библиотека реактивного программирования для iOS, реализующая Observable-паттерн и 400+ операторов трансформации
  • Observable, Subject, Disposable — три фундаментальных типа, образующих основу всех реактивных цепочек
  • Операторы map, flatMap, filter, combineLatest, debounce позволяют строить декларативные цепочки без состояния гонок
  • Schedulers (subscribeOn / observeOn) управляют потоками выполнения, предотвращая блокировку UI
  • RxCocoa предоставляет rx-расширения для UIKit, заменяющие делегаты и target-action реактивными подписками
  • Combine — нативная альтернатива от Apple для iOS 13+, но RxSwift остаётся актуальным для более старых версий

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође