34

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

PassthroughSubject<String, Failure>

CurrentValueSubject<String, Failure>

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

4

5 回答 5

105

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

PassthroughSubject = 门铃按钮

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

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

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

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

于 2020-08-13T22:43:25.823 回答
74

两者都是符合协议的发布者,PassthroughSubject这意味着您可以调用他们随意向下游推送新值。CurrentValueSubjectSubjectsend

主要区别在于它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) })

您会看到current.sink立即使用 调用1。没有调用,passthrough.sink因为它没有当前值。只有在您订阅后发出的值才会调用接收器。

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

current.value // 1
current.value = 5 // equivalent to current.send(5)

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

于 2020-03-06T11:29:46.790 回答
6

PassthroughSubject并且CurrentValueSubject都是Publishers——Combine 引入的类型——你可以订阅(当值可用时对值执行操作)。

它们都旨在使转换为使用组合范式变得容易。它们都有一个值和一个错误类型,您可以向它们“发送”值(使所有订阅者都可以使用这些值)

我见过的两者之间的主要区别是它CurrentValueSubject以一个值开头,而PassthroughSubject不是。PassthroughSubject至少对我来说,从概念上似乎更容易掌握。

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

//Replacing the delegate pattern
class MyType {
    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()

    func doSomething() {
        //do whatever this class does

        //instead of this:
        //self.delegate?.handleValue(value)

        //do this:
        publisher.send(value)
    }
}

//Converting delegate pattern to Combine
class MyDel: SomeTypeDelegate {
    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()

    func handle(_ value: String) {
        publisher.send(value)
    }
}

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

希望这可以帮助!

于 2020-03-02T06:32:44.657 回答
5

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

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

注意:@Published是一种CurrentValueSubject.

于 2021-03-07T20:43:50.273 回答
1

PassthroughSubject适用于点击动作等事件

CurrentValueSubject适合状态

于 2020-09-13T10:45:34.467 回答