Swift Combine: Для чего нужны эти многоадресные функции и как их использовать? - PullRequest
2 голосов
/ 07 июля 2019

Борясь с некоторыми проблемами объединения, я натолкнулся на раздел «Работа с несколькими подписчиками» в https://developer.apple.com/documentation/combine/publisher:

func multicast<S>(() -> S) -> Publishers.Multicast<Self, S>

func multicast<S>(subject: S) -> Publishers.Multicast<Self, S>

Однако, когда я попытался подтвердить свое предположение о необходимости многоадресной рассылки при отправке нескольким подписчикам, я обнаружил, что в этом нет необходимости при попытке использовать этот код игровой площадки (изменен с https://github.com/AvdLee/CombineSwiftPlayground/blob/master/Combine.playground/Pages/Combining%20Publishers.xcplaygroundpage/Contents.swift) (запуск 10.14. .5 в Xcode версии 11.0 бета 3 (11M362v)):

enum FormError: Error { }

let usernamePublisher = PassthroughSubject<String, FormError>()
let passwordPublisher = PassthroughSubject<String, FormError>()

let validatedCredentials = Publishers.CombineLatest(usernamePublisher, passwordPublisher)
    .map { (username, password) -> (String, String) in
        return (username, password)
    }
    .map { (username, password) -> Bool in
        !username.isEmpty && !password.isEmpty && password.count > 12
    }
    .eraseToAnyPublisher()

let firstSubscriber = validatedCredentials.sink { (valid) in
    print("First Subscriber: CombineLatest: Are the credentials valid: \(valid)")
}

let secondSubscriber = validatedCredentials.sink { (valid) in
    print("Second Subscriber: CombineLatest: Are the credentials valid: \(valid)")
}

// Nothing will be printed yet as `CombineLatest` requires both publishers to have send at least one value.
usernamePublisher.send("avanderlee")
passwordPublisher.send("weakpass")
passwordPublisher.send("verystrongpassword")

Это печатает:

First Subscriber: CombineLatest: Are the credentials valid: false
Second Subscriber: CombineLatest: Are the credentials valid: false
First Subscriber: CombineLatest: Are the credentials valid: true
Second Subscriber: CombineLatest: Are the credentials valid: true

так что, похоже, многоадресная рассылка не требуется для адресации нескольких подписчиков. Или я не прав?

Итак, для чего предназначены эти функции многоадресной рассылки и как их использовать? Некоторый пример кода был бы хорош.

Спасибо

Lars

1 Ответ

0 голосов
/ 19 июля 2019

Ответ / ссылка на быстрых форумах подразумевает, что методы многоадресной рассылки должны опираться на оператор .share (). От Сообщение Филиппа :

В этом случае он используется для подключения восходящего потока к объекту PassthroughSubject, а затем автоматически подключается. Обычно, когда подписчик получает подписку, он отменяет любые дополнительные подписки после первой, многоадресная передача выдает аварийный штрих для этого поведения и обрабатывает несколько подписок.

На практике, если вы хотите разделить обновления потока и событий многоадресной рассылки по нескольким конвейерам в Combine, кажется, что наиболее прагматичным способом является создание свойства @Published, когда любой восходящий конвейер обновляет его с помощью .assign () или внутри .sink (), а затем настройте дополнительные конвейеры с подписчиками из свойства @Published.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...