Ответ
Subject — это специальный тип Publisher в фреймворке Combine, который позволяет отправлять значения подписчикам вручную через метод send(). Он сочетает возможности Publisher (отправка значений) и Subscriber (приём значений), что делает его удобным для адаптации императивного кода к реактивному потоку.
Основные типы Subject
PassthroughSubject<Output, Failure>— передаёт значения подписчикам, но не хранит текущее значение. Новые подписчики получают только значения, отправленные после подписки.CurrentValueSubject<Output, Failure>— хранит текущее значение (доступно через свойствоvalue) и немедленно отправляет его новым подписчикам при подписке.
Пример использования
import Combine
// Создание Subject
let subject = PassthroughSubject<String, Never>()
// Подписка
let subscription = subject.sink { value in
print("Получено: (value)")
}
// Ручная отправка значений
subject.send("Привет") // Вывод: Получено: Привет
subject.send("Мир") // Вывод: Получено: Мир
// Завершение потока
subject.send(completion: .finished)
Ключевые особенности
- Управляемая отправка: значения отправляются явно через
send(_:). - Множественные подписчики: один Subject может иметь несколько подписок.
- Завершение потока: можно завершить с ошибкой (
send(completion: .failure(error))) или успешно (send(completion: .finished)). - Мост между императивным и реактивным кодом: часто используется для обёртки делегатов, callback-ов или событий UI в реактивные потоки.