在Swift Combine中,“根”对象是否始终是Subject?

时间:2019-06-12 22:54:27

标签: swift swift5 combine

Swift Combine上的Apple WWDC视频中,他们始终使用NSNotificationCenter作为消息的发布者。但是,Publisher似乎没有任何能力按需实际发送消息。该功能似乎在Subject中。

我是否正确假设Subject必须是Publishers的任何链的根对象? Apple提供了两个内置主题,分别为:CurrentValueSubjectPassthroughSubject

但是我想我可以使用适当的协议写自己的Subject吗?

1 个答案:

答案 0 :(得分:0)

在Swift Combine中, Publishers 是一种协议,它描述了可以随时间传输值的对象。

主题是扩展发布者,知道如何命令式发送。

Publisher和Subject都不是带有实现的具体类;它们都是协议。

看看Publisher协议(并记住主题是扩展的Publisher):

public protocol Publisher {

    associatedtype Output

    associatedtype Failure : Error

    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}

要构建自定义发布者,您只需要实现接收功能(并提供类型信息),就可以在其中授予订阅者访问权限。您将如何从发布者内部将数据发送给该订阅者?

为此,我们查看订户协议以查看可用协议:

public protocol Subscriber : CustomCombineIdentifierConvertible {
...

    /// Tells the subscriber that the publisher has produced an element.
    ///
    /// - Parameter input: The published element.
    /// - Returns: A `Demand` instance indicating how many more elements the subcriber expects to receive.
    func receive(_ input: Self.Input) -> Subscribers.Demand
}

只要您保存了对已连接的所有/所有订阅者的引用,发布者就可以通过在订阅者上调用receive轻松地将更改发送到管道中。但是,您必须自己管理订户和差异更改。

主题的行为相同,但是它没有提供更改到流水线中,而是提供了send函数供其他人调用。 Swift提供的两个具体主题具有存储等其他功能。

TL; DR更改不会发送给发布者,而不会发送给订阅者。主题是可以接受一些输入的发布者。