本篇博客咱们就来聊一下combineLatest()的使用以及具体的实现方式。在以前的《iOS开发之ReactiveCocoa下的MVVM》的博客中咱们已经聊过combineLatest()的用法,虽然是使用老版本的ReactiveCocoa和Objective-C语言介绍的,不过使用原理上都是一致的。都是将两个信号量进行合并,当其中一个信号量发出Value事件时,若是另外一个信号量以前也发送过Value事件,那么就取出最后一个事件的Value值与当前发送的事件值进行合并,而后将合并后的值发送给新的信号量的观察者。若是其中一个未发送过任何Value,那么将不会向合并后的信号量的观察者发送事件。下方会进行详细的叙述。html
下面咱们就来仔细的聊一下combineLatest()的使用方式、具体的代码实现以及合并信号量的工做原理。下方的使用示例咱们仍是与《iOS开发之ReactiveCocoa下的MVVM》这篇博客中聊combineLatest()时使用是示例相同,只不过咱们是使用的Swift语言写的,详情以下。git
1、combineLatest()使用github
下方代码片断是combineLatest()使用方式,介绍以下:swift
首先建立两个信号量,一个是 signalString,用来发送Value值为String类型的信号。另外一个是 signalInt,用来发送Value值为Int类型的信号。
调用信号量 signalString的combineLatest()方法,将signalString信号量最后发送的值与信号量 signalInt最后发送的值进行合并。而后将合并后的元组(String, Int)发送给新建立的combineLatestSignal信号量的全部观察者。
接着就是调用 signalString和 signalInt所对应的 observer对象来发送Value事件了。
从输出结果咱们不难看出,不管是signalString信号量仍是signalInt信号量发出的Value消息,只要是另外一个信号量的LastValue不为nil。那么新的信号量combineSignal的观察者就会收到相应的合并后的值,以下具体结果以下所示:多线程
针对上述的示例,咱们画了下方的简图来讲明合并信号量的工做方式。Letters和Number是两个信号量,Combine是二者经过combineLatest()方法生成的新的信号量,而后Letters和Number信号量就随机发送消息。Combine信号量根据Letter和Numbers发送值的状况进行信号量的输出。具体以下所示。闭包
2、combineLatest()的具体代码实现框架
接下来咱们就来看一下combineLatest()代码的具体实现。下方就是该方法对应的核心代码:函数
首先下方这个泛型函数的参数是一个信号量,而返回值是一个新的信号量,而这个新的信号量的类型是一个能够接受元组的信号量。而这个元组中的两个值就是这两个信号量最后一个值合并而成的。
其次建立了一个 NSLock类型的锁,用来保证多线程下的原子性操做。
定义声明两个常量对象,用来存储两个合并信号量最后发送的值。 CombineLatestState<Value>类的实现是比较简单的,目的就是为了暂存信号量最后发出的值。
而后有定义了一个无参闭包 onBothValue, 而这个闭包体中所作的事情是像新生成的合并信号量发送合并后的元组消息。这样,与新信号量所关联的观察者Observer就会收到这个元组。
紧接着就是建立了一个新的代理观察者observerDelegate, 用来代理新信号量的 Observer来发送各类事件。而这个 observerDelegate代理观察者是代替合并后的新信号量发送事件的。
最后要作的就是将 observerDelegate与要合并的两个信号量进行整合关联,使得要合并的两个信号量中的任何一个信号量发出事件时。在二者都有 LatestValue的状况下,这个新合并的信号量所绑定的观察者均可以接收到该事件。
具体代码以下所示:post
下方这个方法就负责将新的信号量的发送事件的Observer与以前信号量进行整合。具体作法就是往以前的信号量的Bag容器中添加一个新的观察者Observer,在这个新的观察者处理Event事件时,调用ObserverDelegate的相关事件便可。url
在上述代码中,咱们对暂存以前两个信号量最后发出的值的signalState和otherState进行了相关信息的打印。先打印了hashValue,而后打印了其暂存的值。当着两个对象中的latestValue皆不为空时,那么就调用observerDelegate的sendValue方法执行onBothValue闭包,向合并信号量全部的Observer发送元组消息便可。
下方就是对signalState和otherState的相关信息进行的打印 ,从打印信息中咱们能够看出,尽管在observerWithState()函数中是以参数的形式获取的signalState和otherState,可是其内存地址是不变的,独一份。并且当这两个都有lastestValue的状况下,合并信号量的观察者才会收到相应的Value事件。具体以下所示。
3、Latest合并原理图
针对上述的代码实现,以及参考以前博客中原理图的形式,因而乎咱们给出了下方的这个原理图。原理图应该是清晰明了,一目了然的,在此就不作过多的赘述了。经过下图的结构,咱们不难看出,combineLatestSignal信号量仍然是能够进行链式发展的。
在Signal.swift文件中关于SignalProtocol的扩展的方法中,基本上是按照上述的套路来扩展的。大致就是一个方法返回一个新的信号量,这个新的信号量与原始信号量间经过桥接信号量来进行关联。不一样的方法在处理原信号量往新的信号量发送事件时,在中间所作的事情不一样。Signal.swift文件中还有好多相似的方法,在此就不一一进行介绍了,若是你对某个方法的实现感兴趣,能够采用上述的套路来进行解析。
今天的博客就先到这儿,下篇博客咱们会继续解析ReactiveSwift框架中的其余内容。
上述代码github分享地址:https://github.com/lizelu/TipSwiftForRac 。