Combine

Posted liuxiaokun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Combine相关的知识,希望对你有一定的参考价值。

简介

Combine是Apple在2019年WWDC上推出的一个新框架。该框架提供了一个声明性的Swift API,用于随时间处理值。这些值可以表示多种异步事件。

Publisher协议声明了一种可以随时间传递一系列值的类型。Operators根据从upstream publishers接受到的值采取行动,并重新发布这些值。

在publishers链的末尾,Subscriber在接收元素时对其进行操作。Publisher仅在Subscriber明确请求时才会发出值。

通过采用Combine,通过集中事件处理代码并消除嵌套闭包和基于约定的回调等麻烦的技术,使代码更易于阅读和维护。

Combine 是基于泛型实现的,是类型安全的。它可以无缝地接入已有的工程,用来处理现有的 Target/Action、Notification、KVO、callback/closure 以及各种异步网络请求。

在 Combine 中,有几个重要的组成部分:

发布者:Publiser 订阅者:Subscriber 操作符:Operator

技术图片

Publisher

在 Combine 中,Publisher 相当于RxSwift中的 Observable,并且可以通过组合变换(Operator)重新生成新的 Publisher。

public protocol Publisher {

    /// The kind of values published by this publisher.
    associatedtype Output

    /// The kind of errors this publisher might publish.
    ///
    /// Use `Never` if this `Publisher` does not publish errors.
    associatedtype Failure : Error

    /// This function is called to attach the specified `Subscriber` to this `Publisher` by `subscribe(_:)`
    ///
    /// - SeeAlso: `subscribe(_:)`
    /// - Parameters:
    ///     - subscriber: The subscriber to attach to this `Publisher`.
    ///                   once attached it can begin to receive values.
    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}

在 Publisher 的定义中,Output 代表数据流中输出的值,值的更新可能是同步,也可能是异步,Failure 代表可能产生的错误,也就是说 Pubslier 最核心的是定义了值与可能的错误。Publisher 通过 receive(subscriber:) 用来接受订阅,并且要求 Subscriber 的值和错误类型要一致来保证类型安全。

看一个例子:

let justPubliser = Just("Hello")
justPubliser 会给每个订阅者发送一个 "Hello" 消息,然后立即结束(这个数据流只包含一个值)。

Combine提供了一个 enum Publishers,包括:

struct Empty : 一个从不发布任何值的publisher,并且可以选择立即完成。
struct Fail : 立即使用指定错误终止的publisher。
struct Once: 只有一次向每个订阅者发布输出然后完成的publisher,或者在没有生成任何元素的情况下立即失败的publisher。
struct Optional : 如果可选值具有值,则publisher仅向每个订阅者发布一次可选值。
struct Sequence : 发布给定元素序列的publisher。
struct Deferred : 在运行提供的闭包之前等待订阅的发布者,以便为新订阅者创建发布者。
...
Subscriber

Subscriber相当于RxSwift中的Observer。

public protocol Subscriber : CustomCombineIdentifierConvertible {

    /// The kind of values this subscriber receives.
    associatedtype Input

    /// The kind of errors this subscriber might receive.
    ///
    /// Use `Never` if this `Subscriber` cannot receive errors.
    associatedtype Failure : Error

    /// Tells the subscriber that it has successfully subscribed to the publisher and may request items.
    ///
    /// Use the received `Subscription` to request items from the publisher.
    /// - Parameter subscription: A subscription that represents the connection between publisher and subscriber.
    func receive(subscription: Subscription)

    /// 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

    /// Tells the subscriber that the publisher has completed publishing, either normally or with an error.
    ///
    /// - Parameter completion: A `Completion` case indicating whether publishing completed normally or with an error.
    func receive(completion: Subscribers.Completion<Self.Failure>)
}

可以看出,Publisher 在自身状态改变时,调用 Subscriber 的三个不同方法(receive(subscription), receive(_:Input), receive(completion:))来通知 Subscriber。

技术图片

这里也可以看出,Publisher 发出的通知有三种类型:

Subscription:Subscriber 成功订阅的消息,只会发送一次,取消订阅会调用它的 Cancel 方法来释放资源 Value(Subscriber 的 Input,Publisher 中的 Output):真正的数据,可能发送 0 次或多次 Completion:数据流终止的消息,包含两种类型:.finished 和 .failure(Error),最多发送一次,一旦发送了终止消息,这个数据流就断开了,当然有的数据流可能永远没有终止 大部分场景下我们主要关心的是后两种消息,即数据流的更新和终止。

以上是关于Combine的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Combine Framework 共享receiveCompletion 代码块

sas,combine,未知代码数据集观察

Combine如何驯服Future发布器的“怪癖”

在 SwiftUI 中使用 Combine 进行映射、捕获错误和分配

SwiftUI+Combine - 动态订阅发布者的字典

swiftui combine 无法获取数据 [关闭]