Какие преимущества использования Combine в Swift и как он помогает в реактивном программировании?
Что проверяют
Понимаете ли вы модель Combine (издатель, подписчик, операторы, отмена) и где он уместен сейчас рядом с async/await и Observation. Следом почти наверняка спросят про утечки памяти в sink и про отличия от RxSwift.
Как отвечать
Combine это фреймворк Apple (с iOS 13) для обработки значений, приходящих во времени. Базовая модель:
- Publisher: источник значений с типами
OutputиFailure, напримерURLSession.dataTaskPublisher(for:),NotificationCenter.publisher(for:)или свойство с@Published; - Subscriber: получатель, на практике
sinkилиassign; - операторы:
map,filter,debounce,removeDuplicates,combineLatest,flatMap,catch,retry,receive(on:); - AnyCancellable: подписка живёт, пока жив этот объект, их складывают в
Set<AnyCancellable>.
Преимущества лучше показать на примерах. Поиск по мере ввода: цепочка debounce(for:scheduler:), removeDuplicates(), map в запрос и switchToLatest(), старый запрос отменяется, когда пользователь печатает дальше, без таймеров и флагов. Кнопка входа активна, когда оба поля валидны: combineLatest двух издателей. Ошибки типизированы и обрабатываются в одном месте через catch или replaceError(with:). Управление потоком встроено в протокол через Subscribers.Demand.
Честно обозначьте контекст. Для одиночных асинхронных операций стандартом стал async/await, а для наблюдения за моделью в SwiftUI с iOS 17 есть макрос @Observable. Combine силён там, где нужны потоки событий с временными операторами, и в коде с поддержкой iOS 16 и ниже.
Где спотыкаются
Не сохраняют AnyCancellable, и подписка отменяется сразу. Или сохраняют, но сильно захватывают self в замыкании sink и получают цикл удержания, нужен [weak self].
Обновляют интерфейс из фонового потока. Издатель URLSession отдаёт значения не на главном потоке, перед sink нужен receive(on: DispatchQueue.main).
Не понимают, что ошибка завершает поток. После failure издатель больше ничего не пришлёт, поэтому ошибку сетевого запроса ловят внутри flatMap, иначе один сбой сети выключит поиск до перезапуска экрана.