美文网首页
Swift Combine 之 Subject

Swift Combine 之 Subject

作者: Smile_Later | 来源:发表于2022-10-27 10:33 被阅读0次

    Subject

    • 观察者,继承于Publisher,作为一个观察者的身份,可以监听其他源
    • 被观察者,可以发送数据流,提供给Publisher观察数据变化
    • 可以实现自定义的数据源,内置实现了几个实例类

    核心代码

     public protocol Subject: AnyObject, Publisher {
         //发布数据流,Output是Publisher的输入源类型
         func send(_ value: Output)
     
         //数据流完成的触发方式
         func send(completion: Subscribers.Completion<Failure>)
         
         // 发送一个订阅对象
         func send(subscription: Subscription)
     }
    

    主要实现类

    • CurrentValueSubject
      • 会存储send或者init存的流数据,不会丢失
      • 数据流如果触发了完成,后续再发送不会在收到数据流
    • PassthroughSubject
      • 首次不需要给初始值
      • 数据流如果触发了完成,后续再发送不会在收到数据流
    • PublishedSubject
      • @Published 注解内部实现类

    代码演示

    • CurrentValueSubject 演示流程

           let current = CurrentValueSubject<Int, Never>(1)
             current.send(2)
             /// `CurrentValueSubject` 会记录最后一次send的值,当订阅时候,会及时       发出去,相当于热源
             current.send(3)
             /// 订阅
             current.sink {
                 debugPrint("current \($0)")
             }.store(in: &cancel)
             
             current.send(4)
             /// 发布完成以后,订阅不会接收后续的数据流了
             current.send(completion: .finished)
             current.send(5) 
         
           /// 控制台输出:
            "current 3"
            "current 4"
            ```
      
    • PassthroughSubject 演示
      let pass = PassthroughSubject<String, Never>()

         /// Pass
         /// `PassthroughSubject` 不会记录数据,相当于冷源,订阅后发出的数据流才会收到
         pass.send("hello")
      
         /// 订阅
         pass.sink {
             debugPrint("pass  \($0)")
         }.store(in: &cancel)
      
         pass.send("world")
      
         /// 发布完成,后续发送的数据流 不会再被订阅接收
         pass.send(completion: .finished)
         pass.send("over")
      
        /// 控制台输出
        "pass  world"
      
    • PublishedSubject 内置注解类, 和CurrentSubject实现方式类似,但是不能发送完成事件

        /// 回收类,页面释放需要调用cancel
        lazy var cancel: [AnyCancellable] = []
    
        /// 注解类 @Publish内置是一个@propertywrapper 包装了PublishedSubject
        @Published var temperature: Double = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            self.temperature = 1
            self.$temperature.sink { value in
                debugPrint("value is : \(value)")
            }.store(in: &cancel)
            
            self.temperature = 2
            self.temperature = 3
        }
       
        /// 控制器打印
        "value is : 1.0"
        "value is : 2.0"
        "value is : 3.0"
        ```
    

    相关文章

      网友评论

          本文标题:Swift Combine 之 Subject

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