ReactiveSwift源碼解析(七)Signal的CombineLatest的代碼實現
本篇博客我們就來聊一下combineLatest()的使用以及具體的實現方式。在之前的《iOS開發之ReactiveCocoa下的MVVM》的博客中我們已經聊過combineLatest()的用法,雖然是使用老版本的ReactiveCocoa和Objective-C語言介紹的,不過使用原理上都是一致的。都是將兩個信號量進行合并,當其中一個信號量發出Value事件時,如果另一個信號量之前也發送過Value事件,那麼就取出最後一個事件的Value值與當前發送的事件值進行合并,然後將合并後的值發送給新的信號量的觀察者。如果其中一個未發送過任何Value,那麼將不會向合并後的信號量的觀察者發送事件。下方會進行詳細的敘述。
下面我們就來仔細的聊一下combineLatest()的使用方式、具體的代碼實現以及合并信號量的工作原理。下方的使用示例我們還是與《iOS開發之ReactiveCocoa下的MVVM》這篇博客中聊combineLatest()時使用是示例相同,只不過我們是使用的Swift語言寫的,詳情如下。
一、combineLatest()使用
下方代碼片段是combineLatest()使用方式,介紹如下:
-
首先創建兩個信號量,一個是
signalString
,用來發送Value值為String類型的信號。另一個是
signalInt
,用來發送Value值為Int類型的信號。 -
調用信號量
signalString的combineLatest()
方法,將signalString信號量最後發送的值與信號量signalInt
最後發送的值進行合并。然後將合并後的元組(String, Int)發送給新創建的combineLatestSignal信號量的所有觀察者。 -
接著就是調用
signalString
和signalInt
所對應的observer
對象來發送Value事件了。
從輸出結果我們不難看出,無論是signalString信號量還是signalInt信號量發出的Value消息,只要是另一個信號量的LastValue不為nil。那麼新的信號量combineSignal的觀察者就會收到相應的合并後的值,如下具體結果如下所示:
針對上述的示例,我們畫了下方的簡圖來說明合并信號量的工作方式。Letters和Number是兩個信號量,Combine是兩者通過combineLatest()方法生成的新的信號量,然後Letters和Number信號量就隨機發送消息。Combine信號量根據Letter和Numbers發送值的情況進行信號量的輸出。具體如下所示。
二、combineLatest()的具體代碼實現
接下來我們就來看一下combineLatest()代碼的具體實現。下方就是該方法對應的核心代碼:
-
首先下方這個泛型函數的參數是一個信號量,而返回值是一個新的信號量,而這個新的信號量的類型是一個可以接受元組的信號量。而這個元組中的兩個值就是這兩個信號量最後一個值合并而成的。
-
其次創建了一個
NSLock
類型的鎖,用來保證多線程下的原子性操作。 -
定義聲明兩個常量對象,用來存儲兩個合并信號量最後發送的值。
CombineLatestState
類的實現是比較簡單的,目的就是為了暫存信號量最後發出的值。 -
然後有定義了一個無參閉包
onBothValue
, 而這個閉包體中所做的事情是像新生成的合并信號量發送合并後的元組消息。這樣,與新信號量所關聯的觀察者Observer就會收到這個元組。 -
緊接著就是創建了一個新的代理觀察者observerDelegate, 用來代理新信號量的
Observer
來發送各種事件。而這個observerDelegate
代理觀察者是代替合并後的新信號量發送事件的。 -
最後要做的就是將
observerDelegate
與要合并的兩個信號量進行整合關聯,使得要合并的兩個信號量中的任何一個信號量發出事件時。在兩者都有LatestValue
的情況下,這個新合并的信號量所綁定的觀察者都可以接收到該事件。
具體代碼如下所示:
下方這個方法就負責將新的信號量的發送事件的Observer與之前信號量進行整合。具體做法就是往之前的信號量的Bag容器中添加一個新的觀察者Observer,在這個新的觀察者處理Event事件時,調用ObserverDelegate的相關事件即可。
在上述代碼中,我們對暫存之前兩個信號量最後發出的值的signalState和otherState進行了相關信息的列印。先列印了hashValue,然後列印了其暫存的值。當著兩個對象中的latestValue皆不為空時,那麼就調用observerDelegate的sendValue方法執行onBothValue閉包,向合并信號量所有的Observer發送元組消息即可。
下方就是對signalState和otherState的相關信息進行的列印 ,從列印信息中我們可以看出,儘管在observerWithState()函數中是以參數的形式獲取的signalState和otherState,但是其內存地址是不變的,獨一份。而且當這兩個都有lastestValue的情況下,合并信號量的觀察者才會收到相應的Value事件。具體如下所示。
三、Latest合并原理圖
針對上述的代碼實現,以及參考之前博客中原理圖的形式,於是乎我們給出了下方的這個原理圖。原理圖應該是清晰明了,一目了然的,在此就不做過多的贅述了。通過下圖的結構,我們不難看出,combineLatestSignal信號量仍然是可以進行鏈式發展的。
在Signal.swift文件中關於SignalProtocol的擴展的方法中,基本上是按照上述的套路來擴展的。大體就是一個方法返回一個新的信號量,這個新的信號量與原始信號量間通過橋接信號量來進行關聯。不同的方法在處理原信號量往新的信號量發送事件時,在中間所做的事情不同。Signal.swift文件中還有好多類似的方法,在此就不一一進行介紹了,如果你對某個方法的實現感興趣,可以採用上述的套路來進行解析。
今天的博客就先到這兒,下篇博客我們會繼續解析ReactiveSwift框架中的其他內容。
(本文轉載自博客園)
0天安卓課,自己解決住宿問題即可免費學習!
http://www.ujiuye.com/xydt/2017/13748.html?wt.bd=qzb36000j
想就業就就業,優就業就業扶持計劃,拿到滿意的工作offer就是這麼簡單
http://www.ujiuye.com/zt/jyfc/?wt.bd=qzb36000j
※Java 反射 使用及幾種實戰總結
※使用Jenkins進行持續集成ionic3項目
※WPF製作帶明細的環形圖表
※App 組件化/模塊化之路——如何封裝網路請求框架
※vue.js實現內部自定義指令和全局自定義指令——directive
TAG:IT優就業 |
※網關 Spring-Cloud-Gateway 源碼解析——路由之RouteDefinitionLocator一覽
※Bayesian Personalized Ranking 演算法解析及Python實現
※Istio技術與實踐02:源碼解析之Istio on Kubernetes 統一服務發現
※AtomicInteger 源碼解析
※android 訪問webservice(解析一行代碼實現)
※使用 Python的urlliib.parse 庫解析 URL
※druid-spring-boot-starter源碼解析
※技術解析系列PouchContainer Goroutine Leak 檢測實踐
※精讀解析 《When Sophie Gets Angry》
※osg例子解析-osgsimpleshaders
※Photoshop詳細解析CameraRaw插件使用
※長文解析:Gardenscapes的成功和Playrix的轉型分析
※比iPhone SE更香 Switch Lite三大特性解析
※藉助Jackson的JsonTypeInfo註解實現多態類的解析
※Marvell第二代ARM處理器ThunderX2解析:不遜Intel至強
※fileless malware技術解析及檢測
※新一代 Apple Watch Series 4 將提升解析度
※小女友GFRIEND迷你六輯《Time for the moon night》曲目大解析!
※Google 開源 robots.txt 解析器,推動 REP 標準化
※Burberry和Vivienne Westwood 的合作系列已經開售,我們為你帶來完整解析