<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Combine 框架,從0到1 —— 5.Combine 中的 Subjects

       

      本文首發(fā)于 Ficow Shen's Blog,原文地址: Combine 框架,從0到1 —— 5.Combine 中的 Subjects

       

      內(nèi)容概覽

      • 前言
      • PassthroughSubject
      • CurrentValueSubject
      • Subject 作為訂閱者
      • 常見用法
      • 總結(jié)

       

      前言

       

      正所謂,工欲善其事,必先利其器。在開始使用 Combine 進(jìn)行響應(yīng)式編程之前,建議您先了解 Combine 為您提供的各種發(fā)布者(Publishers)、操作符(Operators)、訂閱者(Subscribers)。

      Subject 是一類比較特殊的發(fā)布者,因?yàn)樗瑫r(shí)也是訂閱者。Combine 提供了兩類 SubjectPassthroughSubjectCurrentValueSubject

       

      如果您想了解更多 Publishers 的用法和注意事項(xiàng),可以閱讀:Combine 框架,從0到1 —— 5.Combine 提供的發(fā)布者(Publishers)

       

      PassthroughSubject

      官網(wǎng)文檔

       

      PassthroughSubject 可以向下游訂閱者廣播發(fā)送元素。使用 PassthroughSubject 可以很好地適應(yīng)命令式編程場景。

      如果沒有訂閱者,或者需求為0,PassthroughSubject 就會(huì)丟棄元素。

      示例代碼:

      final class SubjectsDemo {
          
          private var cancellable: AnyCancellable?
          private let passThroughtSubject = PassthroughSubject<Int, Never>()
          
          func passThroughtSubjectDemo() {
              cancellable = passThroughtSubject
                  .sink {
                      print(#function, $0)
                  }
              passThroughtSubject.send(1)
              passThroughtSubject.send(2)
              passThroughtSubject.send(3)
          }
      }
      

      輸出內(nèi)容:

      passThroughtSubjectDemo() 1
      passThroughtSubjectDemo() 2
      passThroughtSubjectDemo() 3

       

      CurrentValueSubject

      官網(wǎng)文檔

       

      CurrentValueSubject 包裝一個(gè)值,當(dāng)這個(gè)值發(fā)生改變時(shí),它會(huì)發(fā)布一個(gè)新的元素給下游訂閱者。

      CurrentValueSubject 需要在初始化時(shí)提供一個(gè)默認(rèn)值,您可以通過 value 屬性訪問這個(gè)值。在調(diào)用 send(_:) 方法發(fā)送元素后,這個(gè)緩存值也會(huì)被更新。

      示例代碼:

      final class SubjectsDemo {
          
          private var cancellable: AnyCancellable?
          private let currentValueSubject = CurrentValueSubject<Int, Never>(1)
          
          func currentValueSubjectDemo() {
              cancellable = currentValueSubject
                  .sink { [unowned self] in
                      print(#function, $0)
                      print("Value of currentValueSubject:", self.currentValueSubject.value)
                  }
              currentValueSubject.send(2)
              currentValueSubject.send(3)
          }
      }
      

      輸出內(nèi)容:

      currentValueSubjectDemo() 1
      Value of currentValueSubject: 1
      currentValueSubjectDemo() 2
      Value of currentValueSubject: 2
      currentValueSubjectDemo() 3
      Value of currentValueSubject: 3

       

      Subject 作為訂閱者

       

      示例代碼:

      final class SubjectsDemo {
          
          private var cancellable1: AnyCancellable?
          private var cancellable2: AnyCancellable?
          
          private let optionalCurrentValueSubject = CurrentValueSubject<Int?, Never>(nil)
          
          private func subjectSubscriber() {
              cancellable1 = optionalCurrentValueSubject
                  .sink {
                      print(#function, $0)
                  }
              cancellable2 = [1, 2, 3].publisher
                  .subscribe(optionalCurrentValueSubject)
          }
      }
      

      optionalCurrentValueSubject 可以作為一個(gè)訂閱者去訂閱序列發(fā)布者 [1, 2, 3].publisher 發(fā)送的元素。

      輸出內(nèi)容:

      subjectSubscriber() nil
      subjectSubscriber() Optional(1)
      subjectSubscriber() Optional(2)
      subjectSubscriber() Optional(3)

       

      常見用法

       

      在使用 Subject 時(shí),我們往往不會(huì)將其暴露給調(diào)用方。這時(shí)候,可以使用 eraseToAnyPublisher 操作符來隱藏內(nèi)部的 Subject

      示例代碼:

          struct Model {
              let id: UUID
              let name: String
          }
          
          final class ViewModel {
              private let modelSubject = CurrentValueSubject<Model?, Never>(nil)
              var modelPublisher: AnyPublisher<Model?, Never> {
                  return modelSubject.eraseToAnyPublisher()
              }
              
              func updateName(_ name: String) {
                  modelSubject.send(.init(id: UUID(), name: name))
              }
          }
      

      外部調(diào)用者無法直接操控 ViewModel 內(nèi)部的 Subject,這樣可以讓 ViewModel 更好地面對(duì)將來可能的改動(dòng)。
      外部調(diào)用者只需要知道 modelPublisherAnyPublisher<Model?, Never> 類型的發(fā)布者即可,無論內(nèi)部采用了 CurrentValueSubject 還是 PassthroughSubject 甚至是其他的發(fā)布者。

       

      總結(jié)

       

      相比于其他的發(fā)布者來說, Subject 是比較容易理解的,而且也是最常用到的。
      只可惜,對(duì)比 Rx 提供的 Subject,Combine 中的 Subject 無法設(shè)置緩沖的大小。也許某天蘋果會(huì)對(duì)此做出調(diào)整吧~

       

      推薦繼續(xù)閱讀:Combine 框架,從0到1 —— 5.Combine 常用操作符

       

      posted @ 2020-09-26 08:07  Ficow  閱讀(624)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 中文字幕va一区二区三区| 亚洲高清 一区二区三区| 精品亚洲一区二区三区在线播放| 天天躁夜夜躁天干天干2020| 国产乱码1卡二卡3卡四卡5| 2018天天拍拍天天爽视频| 久久精品国产99亚洲精品| 国产中文字幕精品在线| 日本三级香港三级三级人!妇久| 人妻影音先锋啪啪av资源 | 久久三级国内外久久三级| 久久久久久久一线毛片| 亚洲a人片在线观看网址| 免费看的日韩精品黄色片| 国产精品任我爽爆在线播放6080| 亚洲国产精品无码久久电影| 亚洲国产精品日韩专区av | 日本高清在线播放一区二区三区| 国产一区二区三区不卡视频 | 大色综合色综合网站| 亚洲日韩性欧美中文字幕| 江西省| 国产蜜臀一区二区在线播放| 国产精品久久福利新婚之夜| 黄骅市| 蜜桃av亚洲精品一区二区| 在线日韩日本国产亚洲| 午夜DY888国产精品影院| 亚洲男人电影天堂无码| 国产高清在线精品一区不卡| 秋霞电影网| 临漳县| 久久96热在精品国产高清| 亚洲一级特黄大片一级特黄| 亚洲日韩国产精品第一页一区| 亚洲国产精品线观看不卡| 影音先锋啪啪av资源网站| 波多野结衣一区二区三区高清| 狠狠色噜噜狠狠狠狠2021| 午夜不卡久久精品无码免费| 久久夜色精品国产噜噜亚洲sv|