上篇博客咱们对Signal的基本实现以及Signal的面向协议扩展进行了介绍, 详细内容请移步于《Signal中的静态属性静态方法以及面向协议扩展》。而且聊了Signal的全部的g功能扩展都是放在Signal所实现的SignalProtocol协议的扩展中的。本篇博客就沿袭上篇博客的内容,咱们来聊一下SignalProtocol的部分扩展。本篇博客咱们主要来聊一下对Signal添加Observer的observe()方法扩展的具体实现,而且聊一下Signal的Map和Filter相关的功能扩展的具体实现。html
固然咱们在聊相关源码的具体实现时,会给出相关的测试用例,而后再根据测试用例来理解其代码实现。git
1、observe()方法的扩展github
首先咱们来看一下observe()方法的扩展。经过前几篇博客的介绍,咱们知道Siganl与Observer之间的关联是经过observe()方法来实现的。而observe()方法的核心实如今上篇博客中已经进行了详细介绍。而在协议扩展中又对observe()方法进行了一些扩展,这些扩展主要是针对一些特定功能为observe()的使用方式添加快捷调用方式。闭包
一、observe()方法扩展的具体实现app
下方个SignalProtocol的延展主要是对observe()方法的扩展,在每一个扩展方法中最后仍是得调用Signal类中所实现的observe()方法。仍是那句话,下方的这些observe()方法的扩展主要仍是Signal类中observe()方法的快捷方式。下方将对observe()的每一个快捷方法进行介绍。框架
observe(action) : 该方法传入的是一个Action闭包,该Action闭包其实就是Observer类中的Action闭包。也就是在调用observe(action)方法时,为Observer的 Action提供了闭包体。而在observe(action)方法中要作的就是实例化Observer对象,并将该对象传给Signal的observe()方法。稍后会给出该扩展方法的使用过程。
observeResult(result):该扩展方法是将Observer的value事件和failed事件分别转换成Result枚举的success和failure。
observeCompleted(completed): 该扩展方法所接收的闭包就是Observer接收completed事件所执行的闭包。
observeFailed(failed): 该扩展方法所接收的闭包就是Observer接收failed事件所执行的闭包。
observeInterrupted(interrupted): 该扩展方法所接收的闭包就是Observer接收interrupted事件所执行的闭包。
从下方代码片断中咱们不难看出,都是在Signal的observe()方法的基础上作的扩展,本质上就是observe()方法的特定使用的快捷方式。函数
二、上述扩展的使用方式post
看完实现,在看上述方法的使用方式就简单多了。下方代码片断就是上述扩展中每一个方法的使用方式。咱们能够根据具体的业务场景以及具体的功能来选择实现那种方法来知足本身的开发需求。从下方每一个方法中的调用方式能够看出,每一个方法在调用时所提供的尾随闭包就是该方法所表示的快捷方式。测试
固然,下方全部的方法,咱们均可以使用Signal中的observe()方法来实现,只不过没有下方这些方法方便快捷。url
2、SignalProtocol的Map扩展
在《ReactiveSwift源码解析之Event与Observer》这篇博客中咱们聊了Event的Map函数,主要是将一个类型的Event(如Event<Value, Error>)转换成另外一个Event类型(如Event<U, Error>)。Signal的Map函数也不例外,也是将一个类型的Signal转换成另外一个类型的Signal。固然,Signal的Map函数本质上仍是使用了Event的Map函数。
根据以前对ReactiveSwift框架的解析,咱们不难发现Signal、Observer以及Event三者要想进行沟通是其泛型类型必须是相同的,也就是一套的。Map函数就是为了解决Signal类型与Observer的类型不匹配而生的。也就是说咱们能够经过Map函数的处理,一个Int类型的Signal能够发送给String类型的Observer的,若是没有Map函数的支持,是作不到这一点的。
能够说Map函数是“适配器模式”的一种应用方式。能够将不一样类型的信号量和观察者进行适配使其正常通讯。接下来咱们就来看一下SignalProtocol协议的Map相关的扩展以及使用方式。
一、map<U>() -> Signal<U, Error> 映射函数
map<U>()就是扩展中的Map相关函数之一。该函数是一个泛型函数,其返还值是一个Signal<U, Error>类型的对象。也就是说,一个Signal<Value, Error>类型的信号量能够经过map<U>()函数映射成一个Signal<U, Error>类型的信号量。固然map<U>()函数的参数是一个尾随闭包,该闭包有map函数的调用者提供,目的就是为了让用户自定义两个信号量之间的映射规则。
首先咱们来看一下map函数的使用方式,下方代码片断中是map函数的使用示例以及输出结果,下方是对这段代码的解释:
首先咱们经过Signal的 pipe()静态方法建立了一个类型为 Signal<Int, NoError>的信号量signal。
而后经过signal的map函数建立了一个新的类型为 Signal<String, NoError>的信号量 mappedSignal。map函数的尾随闭包中就是映射规则,其中value是Int类型,而返回值是String类型。
而后建立了一个 Observer<String, NoError>类型的观察者 subscriber, 并将 subscriber与 mappedSignal进行关联
最后咱们调用 signal的 observer对象发送value事件,该事件所携带的值为整数10。由输出结果咱们能够知道,与 mappedSignal关联的观察者 subscriber尽管只接收String类型的事件,可是通过map函数的处理此刻也是能够收到来自signal的整数值信号量的。
看完map函数的用法后咱们来看一下其具体的代码实现。下方就是上述示例所调用的map()函数的具体实现代码。在map()函数中返回了一个类型为Signal<U, Error>的信号量对象。在Signal的构造器的尾随闭包中又调用了observe(action)方法将新建立的Signal的observer对象所对应的action添加到了以前Signal对象中。
上述代码的执行过程也许有些绕,咱们能够经过一张简图来看一下上述代码的执行过程。下方是对该过程进一步的解释:
首先类型为 Signal<Value, Error>的signal对象调用其 map<U>()函数生成了一个新的类型为 Signal<U, Error>的newSignal对象。
而后经过Event的 map<U>()函数,将signal对象中类型为 Event<Value, Error>的事件经过调用事件的map<U>()函数将其映射成类型为 Event<U, Error>的newEvent事件对象。
而后咱们将新的 newEvent添加到 newSignal的 observer的 action中。
而后使用 newSignal的 observer的action建立一个类型为 Observer<Value, Error>的newObserver对象。
最后将这个新的 newObserver对象添加到旧的 signal的 Bag中。
上述是代码的调用步骤,咱们能够看一下具体的执行过程,以下图所示。从下图的结构咱们不难看出map()函数是链式发展的,下发的mappedSignal还能够调用其本身的map()函数来生成新的Signal对象。在这个链上的全部Observer都会接受到最原始的Signal对象所发出的事件消息。signal与mappedSignal桥接的最终手段仍是Event的map()函数。
二、mapError<F>() -> Signal<U, F> 映射函数
mapError<F>()映射函数的实现机制和使用方式与上述的映射函数即为类似。只不过该映射函数使用了Event的mapError<F>()函数。因该映射仍是的实现方式与上述函数相似,在此就不作过多赘述了。
关于lazyMap<U>()的实现和使用方式,咱们暂且不说,后边聊到SignalProducer以及Flatten时咱们再作补充。
3、SignalProtocol的filter扩展
Filter顾明思议,就是用来过滤东西的。若是你理解上述map的工做原理的话,Filter就显得简单多了。Filter的工做原理以及实现方式与map类似,只不过将Event的map改为了过滤条件。首先咱们将会给出Filter的使用方式,而后在该处Filter的代码实现方式并给出工做原理图。
一、Filter的使用方式
关于Filter的使用,咱们就使用ReactiveSwift官方的示例,下方是对该示例的解释:
首先使用pipe建立一个signal,而后获取到该signal发送消息的句柄observer。
而后经过调用signal的filter()函数来获取过滤信号量filteredSignal,filter()函数的尾随闭包中跟着的是过滤条件。
而后往filteredSignal信号量中添加观察者subscriber。
当使用signal信号量发送事件时,符合过滤条件的事件才会被过滤信号量filteredSignal所关联的观察者接收
下方截图中咱们的过滤条件是事件绑定的值必须大于12,也就大于12的Value事件才会被观察者接受,因此输出的结果只有13和14两个,具体以下所示。
二、Filter的代码实现
看完Filter的使用方式,接下来咱们来看一下Filter的代码实现方式。下方代码片断就是filter函数的具体实现,从代码结构上来看,与上述的map函数差很少,都是返回一个新的Signal对象,新的Signal对象与原来的Signal对象之间有一个桥接观察者来进行通讯的。self.observer()函数后边的闭包就是桥接观察者从原信号量中发出的事件,而后在该事件中根据过滤条件来判断是否向新的信号量所绑定的全部观察者转发该事件。
从下方代码中咱们明确的能够看出,当条件闭包predicate()的值为true时,observer就会对值的事件进行转发,而后过滤信号量所绑定的观察者就能够收到这些事件了。
三、执行原理图
下方就是filter的执行原理图,该图的结构与map()函数的执行结构相似。从下方图中咱们不难看出,filter()函数也是支持链式发展的,就是能够在新的filterSignal的对象上咱们任然能够添加新的过滤条件条件。由于不管是map()仍是filter()函数都会返回一个新的Signal对象,而且二者都是能够链式发展的,因此咱们能够这样去写signal.map().filter().map().filter().filter()……。
在filter下方还有一个filterMap<U>()函数,该函数的主要功能是用来Map的,代码实现方式与与上述的filter相似,只不过是map的功能,可是该map功能有过滤功能,能够过滤掉nil的值。扩展中的skipNil()方法中调用的就是filterMap<U>()函数,在此就不作过多赘述了。
今天的博客就先到这儿,下篇博客咱们会继续解析ReactiveSwift框架中的其余内容。
上述代码github分享地址:https://github.com/lizelu/TipSwiftForRac