上篇博客咱們詳細的聊了ReactiveSwift源碼中的Bag容器,詳情請參見《ReactiveSwift源碼解析之Bag容器》。本篇博客咱們就來聊一下信號量,也就是Signal的的幾種狀態以及Signal的基本實現。固然本篇博客所解析的源碼會用到上篇博客介紹的Bag容器。本篇博客咱們先經過一個示例來看一下Signal是如何工做的,具體說來就是Signal是如何與Observer關聯的,來聊一下Observer是如何觀察和Signal發出的信號的。html
以前咱們也詳細的聊過Observer和Event相關的東西,詳情請參見《ReactiveSwift源碼解析之Event與Observer》。本篇博客咱們先經過一個實例來看一下Signal和Observer的關係,而後在看一下Signal中的幾種狀態,最後看一下Signal是如何給Observer發送事件(通知)的。git
在聊Signal以前,咱們要搞清楚,Signal與Observer的關係是一對多的關係,也就是說Signal是廣播的形式往Observer發事件的。這也就是典型的「觀察者模式」。github
1、Signal的簡單使用示例閉包
接下來咱們先來看一段Signal的使用示例,雖然Single類中有一些建立Signal對象的便利方法,可是下方Demo中咱們採用最原始的Signal建立方式,也就是直接調用Signal的構造器。下方的是對該代碼段的介紹:函數
首先咱們建立了一個Observer的對象 myObserver, 主要是用來給Signal綁定的觀察者來發送事件的。
而後咱們調用Signal的構造器建立了一個Signal的對象mySignal。經過該構造器的尾隨閉包,咱們能夠拿到這個負責給Single所綁定的全部觀察者發送事件的Observer。而後使用 myObserver進行存儲。
接着咱們建立了兩個觀察者,也就是Observer的對象 subscribe01和 subscribe02.
建立好觀察者後,就是將這兩個觀察者與咱們的 mySignal對象進行綁定了。也就是說 subscribe01和 subscribe02這兩個觀察者,觀察mySignal發過來的事件。
最後就是調用mySignal中的 myObserver進行事件的發送了。
從上述示例的輸出結果,咱們能夠看出,當myObserver發送Value事件時,mySignal的全部Value事件的觀察者均可以收到該事件。接下來我咱們就來剖析一下Signal與Observer是如何進行綁定的。以及Signal是如何發送事件的。post
下面咱們能夠經過一個圖來簡單的看一下Signal和Observer的關係。下方畫了一個簡圖來表示這一關係。左邊是咱們建立的多個Observer對象,而後咱們能夠將這些對象與Signal對象進行關聯,這個關聯本質上是將其存放在Signal對象中的Bag中。在Signal對象中也有一個observer對象。Signal的用戶能夠經過Signal構造函數的尾隨閉包來獲取到這個內置的observer對象,也便是上述示例的myObserver,使用這個myObserver對象給Bag中全部的Observer發送相應的事件。url
在myObserver發送事件的方法中,本質上是對Bag中全部元素的遍歷,將myObserver所接受的事件轉發給Bag中全部的元素。接下來咱們要作的事情就是看其具體的實現方式,固然,具體實現是比下方這張簡圖的結構要複雜一些。spa
2、Signal的構造器與observer(observer: Observer)方法server
順藤摸瓜、咱們能夠從上述實例爲切入點來展開對Single實現的解析。在上述實例中咱們使用到了Observer,在以前的博客中咱們對Observer以及Observer所發送事件Event進行詳細的介紹,因此就不對其進行過多贅述了。接下來咱們就把重點放在Signal上。htm
一、Signal的構造器
上述示例初次用到Signal時,是使用的Signal的構造器,接下來咱們就來看一下Signal的構造器的實現。下方代碼段就是Signal類中的核心屬性以及構造方法了。在構造器中咱們能夠看出是對這些屬性進行了初始化。SignalState來標記當前信號量的狀態,在Signal中扮演的角色仍是比較重要的,稍後會進行介紹。兩個NSLock的常量就是兩個同步鎖,保證原子性操做。
最下方就是初始化了一個Observer的常量,這個常量就負責給Signal所綁定的觀察者進行發送事件,經過構造器的尾隨閉包回調給Signal的使用這。該observer常量對應這上述實例的myObserver。observer在初始化時,直接調用的是Observer的構造器,尾隨閉包就是Observer中Action的閉包體。
二、添加觀察者的方法:observer(observer: Observer)
接下來咱們在來看示例中添加觀察者使用到的observer(observer: Observer)方法。下方就是observer()方法的具體實現。
首先咱們來看一下token,token的類型是 RemovalToken, RemovalToken在《 ReactiveSwift源碼解析之Bag容器》中詳細的介紹過。主要是用來移除Bag容器中元素的。
而後判斷當前的Signal是不是 SignalState.alive狀態,若是是的話,取出SignalState.alive狀態所綁定的值snapshot。此處的snapshot就是一個Bag的對象,用來存儲與 Signal所關聯的全部Observer。而後就是 snapshot這個Bag中添加關聯的Observer了,關聯後,就是更新 SignalState.alive所關聯的值了。固然爲了保證狀態更新的原子性操做,這裏使用了 updateLock。
下方負責初始化 Disposable對象,該對象用來將Signal對應的 Observer置爲失效的狀態。本質上就是移除觀察者的操做。 ActionDisposable中主要作的事情就是從Bag中根據Token移除Observer對象。
三、myObserver.send(value)方法
接下來咱們就來看一下在咱們實例中myObserver.send(value)方法所作的事情。也就是Signal構造器中對observer對象賦值是尾隨閉包中要作的事情。下方就是send(value)方法主要作的事情,若是Signal是活躍狀態的話,就會取出該狀態值所綁定的Bag對象,Bag中存儲的是全部和Signal所關聯的Observer,而後遍歷Bag中全部的Observer對象,並調用Observer對的Action閉包執行相應的事件。具體作法以下:
3、SignalState解析
SignalState在Signal中所扮演的角色是比較重要的,由於其中的活躍狀態.alive就關聯着存儲全部能夠接受信號量事件的觀察着的Bag,稍後會進行解析。本部分咱們就來詳細的看一下SignalState中的內容實現。
一、SignalState枚舉的實現
SignalState的代碼實現就比較簡單了,就是一個枚舉。而這個枚舉中有三個枚舉值,這三個枚舉值對應這信號量的三種狀態。
alive狀態表示信號量處於活躍狀態,能夠發送事件,alive狀態有一個AliveState類型的關聯值,稍後會對AliveState進行介紹。
terminating則說明信號量正在被終止,terminating也有一個關聯值,該關聯值是一個TerminatingState類型的值,下方也會介紹到。
terminated狀態說明該信號量處於終止狀態,不可在發事件了。
二、AliveState類的實現
下方就是AliveState類的具體實現,AliveState類的主要做用就是與SignalState.alive狀態進行關聯的。在AliveState中咱們能夠看到有一個observers的屬性,該屬性就是Bag容器,其中可存儲的類型是Observer。也就是說,在信號量活躍狀態下所綁定的觀察者都存儲在這個Bag中。而retaining屬性中存儲的就是與Bag中觀察者所對應的Signal,從這個類結構中能夠看出Signal與Observer是一對多的關係。
三、TerminatingState類的實現
TerminatingState類的實現與AliveState類的實現差很少,下方是TerminatingState類的代碼,在該代碼實現中也有一個存儲着Observer對象的Bag容器。該Bag容器中存儲的是該狀態下所對應的Observer,而下方的Event類型的event屬性則是該狀態所對應的事件。以下所示:
今天博客就先到這兒,下篇博客咱們繼續對ReactiveSwift中的Signal的實現進行介紹。
上述代碼github分享地址:https://github.com/lizelu/TipSwiftForRac