什么是 PassthroughSubject 和 CurrentValueSubject

Nas*_*sir 22 reactive-programming declarative-programming ios swiftui combine

我碰巧研究了 Apple 的新组合框架,在那里我看到了两件事

PassthroughSubject<String, Failure>

CurrentValueSubject<String, Failure>

有人可以向我解释它们的含义和用途吗?

Coş*_*niz 72

我认为我们可以用现实世界的案例进行类比。

PassthroughSubject = 门铃按钮

当有人按门时,只有在您在家时才会收到通知(您是订阅者)

PassthroughSubject 没有状态,它将接收到的任何内容发送给其订阅者。

CurrentValueSubject = 电灯开关 当您在外面时,有人会打开您家中的灯。你回到家,你知道有人打开了它们。

CurrentValueSubject 有一个初始状态,它保留您放入的数据作为其状态。

  • 这是迄今为止我见过的最好的类比。谢谢你! (9认同)

don*_*als 52

双方PassthroughSubjectCurrentValueSubject都符合出版商Subject,这意味着你可以调用协议send对他们的意愿,推动下游的新值。

主要区别在于它CurrentValueSubject具有状态感(当前值)并且PassthroughSubject只是将值直接传递给其订阅者而不记住“当前”值:

var current = CurrentValueSubject<Int, Never>(10)
var passthrough = PassthroughSubject<Int, Never>()

current.send(1)
passthrough.send(1)

current.sink(receiveValue: { print($0) })
passthrough.sink(receiveValue: { print($0) })
Run Code Online (Sandbox Code Playgroud)

您会看到current.sink立即使用 调用1。该passthrough.sink不叫,因为它没有电流值。只会为订阅后发出的值调用接收器。

请注意,您还可以CurrentValueSubject使用其value属性获取和设置 a 的当前值:

current.value // 1
current.value = 5 // equivalent to current.send(5)
Run Code Online (Sandbox Code Playgroud)

这对于直通主题是不可能的。


小智 19

PassthroughSubject用于表示事件。将其用于按钮点击等事件。

CurrentValueSubject用于表示状态。使用它来存储任何值,例如开关状态为关闭和打开。

注意:@Published是一种CurrentValueSubject.


Sam*_*Sam 12

PassthroughSubject和\xe2\x80\x94CurrentValueSubject都是Publisher由 Combine \xe2\x80\x94 引入的类型,您可以订阅它(当值可用时对值执行操作)。

\n\n

它们的设计目的都是为了让您可以轻松地迁移到使用组合范例。它们都有一个值和一个错误类型,您可以向它们“发送”值(使这些值可供所有订阅者使用)

\n\n

我所看到的两者之间的主要区别在于,前者CurrentValueSubject以值开头,而后者则PassthroughSubject不然。PassthroughSubject从概念上来说似乎更容易理解,至少对我来说。

\n\n

PassthroughSubject可以轻松地用来代替委托模式,或者将现有的委托模式转换为组合。

\n\n
//Replacing the delegate pattern\nclass MyType {\n    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()\n\n    func doSomething() {\n        //do whatever this class does\n\n        //instead of this:\n        //self.delegate?.handleValue(value)\n\n        //do this:\n        publisher.send(value)\n    }\n}\n\n//Converting delegate pattern to Combine\nclass MyDel: SomeTypeDelegate {\n    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()\n\n    func handle(_ value: String) {\n        publisher.send(value)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这两个示例都用作String值的类型,但它可以是任何内容。

\n\n

希望这可以帮助!

\n


Jac*_*cky 5

PassthroughSubject适合点击动作等事件

CurrentValueSubject适合状态