Какие проблемы могут возникать при использовании реактивного подхода
Что проверяют
Работали ли вы с RxSwift или Combine на живом проекте, а не по туториалу. У реактивного кода свои болезни: утечки, потерянные подписки, события не на том потоке. Следом часто спрашивают, как вы отлаживаете цепочку и зачем Combine, когда есть async/await.
Как отвечать
Назовите конкретные классы проблем:
- циклы удержания: замыкание в
subscribe(onNext:)илиsinkзахватываетself, аDisposeBagили наборAnyCancellableхранится в том жеself. Объект не освобождается никогда. Лечится[weak self]; - потерянная подписка:
sinkвозвращаетAnyCancellable, и если его не сохранить, подписка отменяется сразу. Цепочка молча не работает; - ошибка завершает поток: после
errorпоследовательность мертва. Если запрос внутриflatMapупал без обработки, кнопка, к которой привязана цепочка, перестаёт реагировать. Ошибку ловят внутриflatMapчерезcatchилиreplaceError; - холодные последовательности: две подписки на один сетевой Observable дают два запроса. Нужен
share()илиshare(replay:); - потоки: событие приходит на фоновой очереди, и UI обновляется не с главного потока. Переключайтесь явно через
observe(on: MainScheduler.instance)илиreceive(on: DispatchQueue.main); - отладка: стек вызовов состоит из внутренностей фреймворка. Помогают
debug()в RxSwift,print()иhandleEventsв Combine.
Хорошо добавить, что для простых задач сейчас хватает async/await и @Observable, а реактивный подход оставляют там, где правда нужны потоки событий: поиск с debounce, объединение источников через combineLatest.
Где спотыкаются
Забывают, что @Published отдаёт значение в willSet: внутри sink свойство объекта ещё старое, новое приходит только аргументом замыкания.
Ставят [weak self] механически везде и не могут объяснить, где цикл реально возникает.
Держат всё состояние экрана в BehaviorSubject и PassthroughSubject, доступных отовсюду. Они становятся глобальными изменяемыми переменными, и поток данных уже не прослеживается.