ReactiveSwift源碼解析(四) Signal中的靜態屬性靜態方法以及面向協議擴展

上篇博客咱們聊了Signal的幾種狀態、SignalObserver的關聯方式以及Signal是如何向關聯的Observer發送事件的。本篇博客繼續上篇博客的內容,來聊一下Signal類中靜態的neverempty計算屬性以及pipe()靜態方法。而後再聊聊Signal中的面向協議編程中的面向協議擴展。在Signal中,只要是對Signal的擴展都是加在了Signal所實現的協議中,稍後會進行介紹。git

 

1、Signal中獲取實例的靜態計算屬性github

在本篇博客的第一部分咱們先來看看Signal類中的兩個屬性,一個是never,另外一個是empty。之因此將這兩個計算屬性放在一塊,是由於這兩個靜態計算屬性都是用來獲取Signal實例的。可是所獲取實例的功能不一樣。解析來咱們就來看一下never以及empty的實現和使用方式。編程

1. never閉包

下方是never是代碼實現,實現比較簡單。其中就是調用了Signal的構造器,可是沒有在構造器的尾隨閉包中作任何事情。經過該計算屬性獲取的Signal對象,不會獲取到內置的Observer對象,從而Signal的對象持有者是不能對Signal所關聯的觀察者發送事件的。測試

  

 

下方是ReactiveSwift官方關於never的測試用例以及輸出結果。從運行結果中來看,所關聯的Observer對象是不會收到來自Signal的任何消息的。spa

  

 

二、empty設計

聊完never,接下來咱們來看一下Signal的靜態計算屬性empty的實現以及執行方式。empty的使用方式與never差很少,empty形式的Signal在管理Observer時,只會執行該Observer的interrupted事件。解析下來咱們就來看一下empty的實現方式。3d

咱們先看一下empty的使用方式,下方這段代碼就是ReactiveSwift官方的empty使用的示例,以及該示例的輸出結果。咱們從Signal的靜態計算屬性empty中獲取Signal是實例。而後在關聯Observer時,都會執行Observer的interrupted事件的閉包體。server

  

 

接下來咱們來看一下empty的實現方式,代碼比較簡單,比never就多了一個observer.sendCompleted()方法。在以前咱們聊Observer時,咱們知道sendCompleted()就是執行觀察者的Event.completed事件。sendComplented()會執行Observer中的Action,並帶有.completed事件。對象

  

 

下方這個代碼段中Observer初始化時的尾隨閉包,就是observer.sendComplented()方法所執行的內容。而在這個尾隨閉包中,咱們看到有一個event.isTerminating的判斷,當是.failed、.completed 和 .interrupted事件時event.isTerminating的值都是true。因此該if塊中就是empty要執行的方法。

在if語句塊中,核心的內容就是修改當前Single的SignalState。當調用Signal的構造器時,SignalState默認是SignalState.alive(AliveState()),而if語句塊中就負責將該狀態修改爲TerminatingState狀態,以下所示。

在關聯Observer時,會用到TerminatingState狀態,下方會給出介紹。

  

 

下方代碼段就是Signal關聯Observer是所調用的方法。從下方代碼不難看出,當Signal處於非活躍狀態.alive時,token的值就是nil,當token未賦值時,就會執行所關聯對象Observer的sendInterrupted()方法,向所關聯的Observer發送.interrupted事件,從而執行Observerinterrupted的閉包體。至此,empty的相關內容就解析完了。

  

 

 

2、Signal的靜態方法pipe()

Signal中的靜態方法pipe()本質上就是一個便利構造器,該便利構造器返回的參數是一個元組,其不單單返回一個Signal的實例,並且返回Signal用於發送事件的內置observer對象。pipe()是獲取Signal實例的主要方式,接下來咱們就來看一下pipe的使用方式以及pipe()的內部實現。

一、pipe()的使用示例

下方這個pipe()的應用示例是從官網Demo的基礎上修改的,下方是對該段代碼的介紹:

  • 首先經過Signal的pipe()靜態方法能夠獲取一個Signal實例以及該實例所持有的Observer對象,也就下方元組中的(signal, sendMessage)。
  • 緊接着咱們建立兩個Observer對象,而且給出Value事件所執行的閉包體。咱們將這兩個Observer的實例命名爲subscriber1和subscriber2。
  • 而後咱們將subscriber1添加到signal中,在signal調用observe()方法添加Observer時,會返回一個ActionDisposable類型的對象,咱們可使用該對象移除觀察者。添加完畢後,咱們就調用sendMessage的send(value)方法,發送value事件,而後觀察者subscriber1所對應的Value事件閉包體就會獲得執行。
  • 咱們以一樣的方將subscriber2添加到Signal中,而後經過是調用sendMessage的send(value)方法,發送value事件。咱們就能夠看到subscriber1和subscriber2這兩個觀察者的Value閉包就會執行。
  • 而後咱們調用actionDisposable對象的dispose()方法,將subscriber1從Signal的Bag中移除掉。移除後subscriber1就不會收到來自Signal的事件了。actionDisposable對象的dispose()方法稍後會介紹到。
  • 咱們再次調用sendMessage的send(value)方法,subscriber1的Value事件的閉包就不會被執行。

  

 

二、pipe()的代碼實現

pipe()的代碼實現比較簡單,就是經過元組將Signal的對象以及Observer的對象進行返回便可,下方就是pipe()的代碼實現。因其實現比較簡單,在此就不作過多贅述了。

  

 

 

三、ActionDisposable的代碼實現

接下來咱們來解析一下ActionDisposable的代碼實現,在每次觀察者Observer與Signal調用observe()方法進行關聯時都會返回一個ActionDisposable對象,該對象能夠是對應的觀察者取消對Signal信號的觀察。接下來咱們就來看一下ActionDisposable的具體實現。

下方就是ActionDisposable類的實現,ActionDisposable的代碼實現比較簡單,本質上就是經過構造器接收一個閉包,而後將這個尾隨閉包賦值給action變量,而後在dispose()方法中去調用該action閉包。

  

 

下方就是在關聯Observer和Signal的observe()方法中實例化ActionDisposable的相關代碼。下方的大紅框中就是ActionDisposable方法中action的閉包體,也是dispose()方法中主要執行的代碼。在改閉包中所執行的目的也是比較單一的,其中主要作了一件事情,就是根據token從Signal活躍狀態的Bag中移除相應的Observer,換句話說就是移除觀察者

  

 

 

 3、Signal的可擴展性

在本篇博客的最後一部分,想聊一下Signal的可擴展性設計。對Signal功能的擴展,主要使用了面向協議擴展的形式。主要就是是Signal實現SignalProtocol,而後咱們對 SignalProtocol這個協議進行擴展,而不是對Signal這個類自己進行擴展。因此此處咱們稱之爲「面向協議擴展」,對SignalProtocol這個協議進行擴展後,由於Signal這個類遵循SignalProtocol,因此Signal也會擁有SignalProtocol所擴展的功能。

下方截圖中就是SignalProtocol的實現以及相應的擴展。從下方代碼中咱們能夠看到,Signal類的大部分核心功能都是經過SignalProtocol的協議擴展而擁有的。SignalProtocol有好多擴展,本篇博客就不細說了,下篇博客咱們找一些比較核心的SignalProtocol的擴展拿出來聊聊。

  

今天博客就先到這兒,下篇博客咱們會對ReactiveSwift中的SignalProtocol的延展的實現進行介紹。

上述代碼github分享地址:https://github.com/lizelu/TipSwiftForRac  

相關文章
相關標籤/搜索