Swift Combine:这些多播功能有什么作用,我该如何使用它们? [英] Swift Combine: What are those multicast functions for and how do I use them?
问题描述
在遇到一些合并问题时,我在 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
接收器a
和b
正在获得彼此不同的一系列数字,这实际上是因为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()
来完成相同的事情.我不清楚multicast
和share
之间的区别是什么.
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屋!