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  

相关文章
相关标签/搜索