美文网首页Swift
Combine进化之路3——Subscriber

Combine进化之路3——Subscriber

作者: valiant_xin | 来源:发表于2023-09-10 09:32 被阅读0次

    和Publisher相对应的,Subscriber就是观察者模式中的Observer。

    @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
    public protocol Subscriber<Input, Failure> : 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 `Subscribers.Demand` instance indicating how many more elements the subscriber 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 ``Subscribers/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。


    111.png

    Publisher发出的通知有三种类型:

    · Subscription:Subscriber成功订阅的消息,只会发送一次,取消订阅会调用它的cancel方法来释放资源。
    · Value(Subscriber的Input,Publisher的Output):真正的数据,可能发送0次或多次。
    · Completion:数据流终止的消息,包含两种类型:.finished 和 .failure(Error),最多发送一次,一旦发送完数据流就断开了,有的数据流可能永远没有终止。

    大部分场景下,我们需要关心后两种消息:数据流更新和终止。

    Combine内置的Subscriber有三种:
    · Sink
    · Assign
    · Subject

    Sink

    Sink是非常通用的Subscriber,我们可以自由的处理数据流状态。

    func subscriberFunc() {
            let oncePublisher = Just(100)
            let subscriber = Subscribers.Sink<Int, Never> {
                print("completed: \($0)")
            } receiveValue: { input in
                print("receive: \(input)")
            }
            oncePublisher.receive(subscriber: subscriber)
        }
    

    publiser还提供了sink方法来简化整个流程

    func sinktestFunc() {
            let _ = Just(100).sink {
                print("comp: \($0)")
            } receiveValue: {
                print("receive: \($0)")
            }
        }
    

    Assign

    Assign可以很方便的将接收到的值通过KeyPath设置到指定的Class上(不支持Struct),很适合将已有的程序改造成Reactive。

    class People {
            let name: String
            var age: Int
            
            init(name: String, age: Int) {
                self.name = name
                self.age = age
            }
        }
        func assignTestFunc() {
            let p = People(name: "allien", age: 19)
            print("I'm \(p.name), I'm \(p.age) years old.")
            let subscriber = Subscribers.Assign(object: p, keyPath: \People.age)
            let publisher = PassthroughSubject<Int, Never>()
            publisher.subscribe(subscriber)
            publisher.send(20)
            print("I'm \(p.name), I'm \(p.age) years old.")
            publisher.send(22)
            print("I'm \(p.name), I'm \(p.age) years old.")
        }
    

    经测试后发现,一旦publisher改变了值(调用send方法),People的age也会同步改变。

    PassthroughSubject这里是Combine内置的一个Publisher。Subject是中间代理,它有时可能会作为发布者角色出现。

    Combine进化之路合集

    相关文章

      网友评论

        本文标题:Combine进化之路3——Subscriber

        本文链接:https://www.haomeiwen.com/subject/zlolvdtx.html