В Swift Combine всегда ли корневой объект является Субъектом? - PullRequest
0 голосов
/ 13 июня 2019

В видео Apple WWDC на Swift Combine они всегда используют NSNotificationCenter в качестве издателя сообщений. Однако Publisher, по-видимому, не имеет возможности фактически отправлять сообщения по требованию. Похоже, что эта функциональность есть в Subject.

Правильно ли я считаю, что Subject должен быть корневым объектом любой цепочки Publishers? Apple предоставляет две встроенные темы: CurrentValueSubject и PassthroughSubject.

Но я предполагаю, что могу написать свой собственный Subject, используя соответствующие протоколы?

1 Ответ

0 голосов
/ 20 июня 2019

В Swift Combine Publishers - это протокол, описывающий объект, который может передавать значения во времени.

Субъект - это расширенный издатель, который знает, как отправить.

Ни Publisher, ни Subject не являются конкретными классами с реализацией; оба протокола.

Взгляните на протокол Publisher (и помните, что Subject является расширенным Publisher):

public protocol Publisher {

    associatedtype Output

    associatedtype Failure : Error

    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}

Чтобы создать собственного издателя, вам нужно только реализовать функцию приема (и предоставить информацию о типе), в которой вам предоставляется доступ к подписчику. Как бы вы отправили данные этому подписчику ВНУТРИ издателя?

Для этого мы смотрим на протокол подписчика, чтобы увидеть, что доступно:

public protocol Subscriber : CustomCombineIdentifierConvertible {
...

    /// Tells the subscriber that the publisher has produced an element.
    ///
    /// - Parameter input: The published element.
    /// - Returns: A `Demand` instance indicating how many more elements the subcriber expects to receive.
    func receive(_ input: Self.Input) -> Subscribers.Demand
}

Пока вы сохранили ссылку на любого / всех подписчиков, которые подключились, ваш издатель может легко отправлять изменения в конвейер, вызывая receive на подписчике. Однако вам придется управлять подписчиками и самостоятельно вносить изменения.

Субъект ведет себя так же, но вместо потоковой передачи изменений в конвейер, он просто предоставляет функцию send для вызова другим человеком. Два конкретных предмета, которые предоставляет Swift, имеют дополнительные функции, такие как хранилище.

TL; изменения DR не отправляются издателям они отправляются подписчикам. Субъекты - это издатели, которые могут принять некоторые данные.

...