Swift Combine:这些多播功能有什么作用,我该如何使用它们? [英] Swift Combine: What are those multicast functions for and how do I use them?

查看:574
本文介绍了Swift Combine:这些多播功能有什么作用,我该如何使用它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在遇到一些合并问题时,我在 https:中遇到了使用多个订户"部分: //developer.apple.com/documentation/combine/publisher :

Struggling with some combine problems I came across the "Working with Multiple Subscribers" section in https://developer.apple.com/documentation/combine/publisher :

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

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

但是,当我尝试确认我的假设,即发送给多个订阅者时将需要多播时,我发现在尝试使用此操场代码(从

However, when I tried to confirm my assumption that multicast would be needed when sending to multiple subscribers, I found out this is not necessary when trying on this playground code (modified from https://github.com/AvdLee/CombineSwiftPlayground/blob/master/Combine.playground/Pages/Combining%20Publishers.xcplaygroundpage/Contents.swift ) (run on 10.14.5 in Xcode Version 11.0 beta 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

因此,似乎不需要多播即可寻址多个订户.还是我错了?

so it seems that no multicast is needed to address multiple subscribers. Or I am wrong?

那么,这些多播功能有什么作用,我将如何使用它们?一些示例代码会很好.

So, what are those multicast functions for and how would I use them? Some example code would be nice.

谢谢

Lars

推荐答案

PassthroughSubject并不是一个很好的示例,因为它是一个类,并且为您提供了参考语义.因此,在一个简单的情况下,每当主题发出一个主题时,两个订阅者就可以直接订阅它并同时接收相同的值.

PassthroughSubject is not a very good example to test with, because it's a class and gives you reference semantics. Therefore in a simple case two subscribers can subscribe directly to it and receive the same values at the same time whenever the subject emits one.

但这是一个更好的测试用例(灵感来自可可与爱(a)):

But here's a better test case (inspired by a discussion on Cocoa With Love):

    let pub1 = Timer.publish(every: 1, on: .main, in: .default).autoconnect()
    let sub = CurrentValueSubject<Int,Never>(0)
    let scan = sub.scan(10) {i,j in i+j}
    pub1.sink { _ in let i = sub.value; sub.value = i+1 }.store(in:&storage)
    scan.sink { print("a", $0) }.store(in:&storage)
    delay(3) {
        scan.sink { print("b", $0) }.store(in:&self.storage)
    }

当第二个sink作为该管道的新订阅者出现时,得出的结果肯定很奇怪:

That gives a decidedly weird result when the second sink comes along as a new subscriber to this pipeline:

a 10
a 11
a 13
a 16
b 13
a 20
b 17
a 25
b 22
a 31
b 28
a 38
b 35

接收器ab正在获得彼此不同的一系列数字,这实际上是因为scan是一个结构.如果我们希望他们获得相同的数字,则可以使用多播:

Sinks a and b are getting a different series of numbers from one another, effectively because scan is a struct. If we want them to get the same numbers, we can use a multicast:

    let scan = sub.scan(10) {i,j in i+j}.multicast {PassthroughSubject()}.autoconnect()

这产生了

a 10
a 11
a 13
a 16
a 20
b 20
a 25
b 25

这是连贯的.

但是, still 并不能证明您需要multicast,因为您可以通过说.share()来完成相同的事情.我不清楚multicastshare之间的区别是什么.

However, that still doesn't prove you need multicast, because you could accomplish the same thing by saying .share() instead. I'm not clear on what the difference is between multicast and share.

这篇关于Swift Combine:这些多播功能有什么作用,我该如何使用它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆