Skip to content

Latest commit

 

History

History
68 lines (47 loc) · 3.28 KB

4.1.4.5 Subscriber.md

File metadata and controls

68 lines (47 loc) · 3.28 KB

Subscriber — это конечная точка потока данных, далее будем называть его подписчик. По сути это объект, который подписывается на паблишер и взаимодействуют с полученными и паблишера данными. В Combine, имеется 2 встроенных подписчика: Sink и Assign, оба соответствуют протоколу Subscriber.

Протокол представлен с двумя ассоциированными типами: Input и Failure.

Input — данные определенного типа, который он может обработать.

Failure — ошибка, которая может прийти от паблишера.

public protocol Subscriber<Input, Failure> : CustomCombineIdentifierConvertible {
    associatedtype Input
    associatedtype Failure: Error
}

Sink

.sink — это и есть подписчик, метод создает подписчика и сразу запрашивает неограниченное число значений. Посмотрите на его сигнатуру:

func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable

Пример:

sequencePublisher
    .sink { receivedValue in
        print(receivedValue)
    }

Метод .sink() возвращает объект с типом AnyCancellable — это класс-обертка, которая стирает тип данных подписчика.

У AnyCancellable есть 2 метода:

.cancel() — позволяет отменять подписку на паблишер. Мы можем его вызвать ручками при необходимости, но AnyCancellable может вызывать его автоматически при деинициализации объекта, если мы сохраним подписку с помощью второго метода.

.store(in:) — позволяет сохранить подписку на паблишер в коллекцию.

Assign

https://shayanbo.medium.com/dive-in-combine-part-iii-6eeb0aab2304

В большинстве случаев Sink достаточно. Но когда мы работаем над обновлением свойств экземпляра путем подписки на Publisher. Для нас есть более простой подписчик под названием Assign. Мы можем использовать Assign для обновления свойств, указав его KeyPath.

Пример:

class Person {
    @Published var name = "Yanbo Sha"
}
class View {
    var text = ""
}
let view = View()
let person = Person()
let cancellable = person.$name.assign(to: \.text, on: view)
person.name = "Rock"
print(view.text) /// "Rock" 

4.1.4.4 Operators Theme | Back To iOSWiki Contents | 4.2 IosDevTools Theme Folder