在前面幾篇博客中咱們詳細的聊了ReactiveSwift中的Bag、Event、Observer以及Signal的使用方式和代碼實現。那麼在接下來的這幾篇博客中,咱們就依附於以前博客的基礎上來聊一聊SignalProducer的用法以及內部的代碼實現。從SignalProducer的名字中,咱們容易知道,SignalProducer是信號量的生產者,確切的說,SignalProducer基於Signal的又一層封裝。擴充了Signal的使用方式,使其更貼近於一些業務場景,好比網絡的請求等。git
接下來咱們看一下SignalProducer的基本實現,也就是看一下SignalProducer一些核心的構造器和核心的方法。而且給出這些構造器以及核心方法的代碼解釋並給出其對應的使用方式。github
1、SignalProducer的核心屬性、方法和構造器數組
開門見山,在本篇博客的第一部分咱們先給出SignalProducer結構體的核心屬性、構造器和方法。下方會對這些SignalProducer的核心內容進行介紹,而後再看一下其具體的使用和運行方式。之因此說本部分所介紹的內容是SignalProducer的核心,由於SignalProducer的其餘方法、構造器是在下方所要介紹的內容的基礎上所創建起來的。網絡
一、startHandler屬性、init(startHandler)構造器以及startWithSignal()的方法實現閉包
startHandler屬性是SignalProducer結構體的基本實現中的惟一屬性。從下方代碼片斷中咱們能夠看出startHandler的類型是一個閉包類型。該閉包類型的的參數是Observer和Disposable類型的對象,返回值爲空。併發
而緊接着下方的init(startHandler)構造器就是爲startHandler屬性賦值的。雖然該init(startHandler)構造方法簡單,可是是SignalProducer結構體的核心,由於在SignalProducer其餘構造器中直接或者間接調用了下方的構造方法,稍後咱們會給出相應的代碼實現。 框架
上述代碼片斷中的startWithSignal(setup)方法,也是SignalProducer結構體中比較核心的方法。由於在SignalProducer結構體的擴展方法中直接或者間接的調用了該方法。該方法中作的事情比較單一,就是調用Signal的pipe()方法建立了一個signal對象與該對象所對應的observer對象。該方法的參數是一個名爲setup的閉包,將建立的signal對象交給setup()閉包,將observer對象交給startHandler()閉包。而startHandler的閉包體就是init(startHandler)構造器的尾隨閉包。spa
二、上述屬性和方法的使用server
上述的屬性和方法之因此是SignalProducer結構體的核心,是由於SignalProducer的其餘構造器以及擴展方法都是在此基數上構建起來的,稍後咱們會介紹到。如今咱們來看一下上述方法的調用方式。下方就是咱們給出的針對上述方法的示例和輸出結果。對象
首先調用了SignalProducer的 init(startHandler)構造器,建立了一個producer常量。在該構造器的尾隨閉包中,咱們能夠經過閉包回調的形式獲取到producer中signal對象所對應的observer,咱們能夠經過該對象發送一些值,以下所示。
而後咱們建立了一個Observer類的 subscribe1對象,並給出了該觀察者的Value事件的處理閉包。
最後咱們調用 startWithSignal啓動producer的信號量,經過 startWithSignal()方法的尾隨閉包,咱們能夠獲取到producer中的signal對象,而後將咱們建立的subscriber觀察者與該signal進行關聯。關聯後,subscriber或收到producer中的observer對象所發送的Value事件。
最下方就是該段代碼的運行結果,以下所示。
2、SignalProducer中的其餘構造器
上面咱們聊了SignalProducer的核心構造器,在SignalProducer結構體的構造器陣營中,其構造器都是在上述核心構造器的基礎上衍生出來的快捷構造器。這些衍生出來的構造器適用於特定場景下的SignalProducer的初始化,其功能更爲專注,使用更爲便捷。接下來咱們就來介紹一下這些衍生構造器的代碼實現以及使用方式。
一、init(signal)和init(value)
下方代碼片斷就是init(signal)和init(value)的具體實現,從下方代碼片斷中咱們容易看出,最終都是調用的上述咱們介紹的init(startHandler)這個構造器。只不過在startHandler這個閉包塊中所作的事情不一樣罷了。
咱們先來看init(signal),該構造器接收一個signal信號量,而後將producer中的observer對象添加爲該參數signal信號量的觀察者,也就是說當這個信號量發送消息是,producer中的observer會收到這個外部信號量發過來的消息,而後通知producer中內部的信號量的全部觀察者。針對上述代碼實現咱們能夠畫出下方的簡圖。左邊的mySignal就是經過init(signal)構造器傳過來的信號量對象,mySignal信號量中的Bag中存儲了一些該信號量的觀察者。而後調用SignalProducer的init(signal)方法將mySignal信號量傳給SignalProducer,而後將SignalProducer中的內部信號量signal所對應的observe添加到mySignal的Bag中,使其成爲mySignal信號量的觀察者。具體以下所示,稍後咱們會給出具體使用方式。
上述init(value)構造器就簡單的多了,就是在調用init(startHandler)構造器的尾隨閉包中調用SignalProducer內部的observer將init(value)提供的參數發送出去。發送完畢後就調用Observer的sendCompleted()方法,完成信號量的發送。
接下來咱們來看一下上述兩個構造器的使用示例以及示例的運行結果。
首先咱們來看一下 init(signal)的使用示例。首先建立了一個mySignal信號量以及該信號所對應的myObserver。而後調用init(signal)構造器,並把mySignal對象傳給該構造器。接着經過startWithSignal()方法往producer中的signal中添加一個名爲subscriber1觀察者。而後調用myObserver發送Value信號量,咱們能看到,producer中信號量的觀察者subscriber1也能收到該信號量。
而 init(value)構造器的使用就簡單許多,直接在SignalProducer建立時,將SignalProducer所對應的信號量所須要發送的值傳進去便可,以下所示。
二、init(action)、init(error)以及init(result)構造器
接下來咱們再來看一下這init(action)、init(error)以及init(result)三個構造器,這個三個構造器也是直接或者間接的調用了咱們以前的核心構造器init(startHandler)。下方就是這三個構造器的具體代碼實現:
init(action)構造器接收了一個名爲action的無參閉包,該閉包的返回值爲Value。從其代碼實現咱們不難看出,下方代碼就等同於 self.init(value: action())。action閉包的做用就是爲 observer.send(value)提供值的。
init(error)構造器中就是在調用 init(startHandler)時,在其尾隨閉包中的獲取到observer而後調用 send(error)方法,發送Failure事件。
init(result)構造器接收的是一個 Result枚舉對象,目的就是將Result枚舉中的 success轉換成 Value事件,將failure結果轉換成failure事件併發送相應的Error。
由於該三個構造方法比較簡單,就不提供相應的使用示例了,若是你感興趣,能夠在官方提供的Playground中進行示例的編寫。
三、init(values)和init(first, second, tail…)構造器
本小節咱們就來聊一下init(values)和init(first, second, tail)這兩個構造器,這兩個構造器的功能其實差很少,實現方式也是相同的,只不過是調用方式不一樣。下方是這兩個構造器具體的代碼實現。
init(values)構造器接收的是一個可遍歷的序列,在具體的代碼實現中,咱們遍歷該序列,取出其中的每一個值,而後調用 observer的send(value)方法將該值進行發送。遍歷完成後,調用了 sendCompleted()方法完成信號量的發送。
init(first, second, tail ...)構造器是一個不定參構造器。在該構造器中,咱們將收到的參數組合成數組,而後調用init(values)構造器,具體實現以下。
針對上述的構造器,咱們給出了下方這兩個使用示例,以及相應示例的輸出結果。
今天的博客就先到這兒,下篇博客咱們會繼續解析ReactiveSwift框架中的其餘內容。
上述代碼github分享地址:https://github.com/lizelu/TipSwiftForRac 。