博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactiveSwift源码解析(七) Signal的CombineLatest的代码实现
阅读量:5876 次
发布时间:2019-06-19

本文共 2560 字,大约阅读时间需要 8 分钟。

本篇博客我们就来聊一下combineLatest()的使用以及具体的实现方式。在之前的《》的博客中我们已经聊过combineLatest()的用法,虽然是使用老版本的ReactiveCocoaObjective-C语言介绍的,不过使用原理上都是一致的。都是将两个信号量进行合并,当其中一个信号量发出Value事件时,如果另一个信号量之前也发送过Value事件,那么就取出最后一个事件的Value值与当前发送的事件值进行合并,然后将合并后的值发送给新的信号量的观察者。如果其中一个未发送过任何Value,那么将不会向合并后的信号量的观察者发送事件。下方会进行详细的叙述。

下面我们就来仔细的聊一下combineLatest()的使用方式、具体的代码实现以及合并信号量的工作原理。下方的使用示例我们还是与《》这篇博客中聊combineLatest()时使用是示例相同,只不过我们是使用的Swift语言写的,详情如下。

 

一、combineLatest()使用

下方代码片段是combineLatest()使用方式,介绍如下:

  • 首先创建两个信号量,一个是
    signalString,用来发送Value值为String类型的信号。另一个是
    signalInt,用来发送Value值为Int类型的信号。
  • 调用信号量
    signalString的combineLatest()方法,将signalString信号量最后发送的值与信号量
    signalInt最后发送的值进行合并。然后将合并后的元组(String, Int)发送给新创建的combineLatestSignal信号量的所有观察者。
  • 接着就是调用
    signalString
    signalInt所对应的
    observer对象来发送Value事件了。

从输出结果我们不难看出,无论是signalString信号量还是signalInt信号量发出的Value消息,只要是另一个信号量的LastValue不为nil。那么新的信号量combineSignal的观察者就会收到相应的合并后的值,如下具体结果如下所示:

  

 

针对上述的示例,我们画了下方的简图来说明合并信号量的工作方式。LettersNumber是两个信号量,Combine是两者通过combineLatest()方法生成的新的信号量,然后LettersNumber信号量就随机发送消息。Combine信号量根据LetterNumbers发送值的情况进行信号量的输出。具体如下所示。

  

 

 

二、combineLatest()的具体代码实现

接下来我们就来看一下combineLatest()代码的具体实现。下方就是该方法对应的核心代码:

  • 首先下方这个泛型函数的参数是一个信号量,而返回值是一个新的信号量,而这个新的信号量的类型是一个可以接受元组的信号量。而这个元组中的两个值就是这两个信号量最后一个值合并而成的。
  • 其次创建了一个
    NSLock类型的锁,用来保证多线程下的原子性操作。
  • 定义声明两个常量对象,用来存储两个合并信号量最后发送的值。
    CombineLatestState<Value>类的实现是比较简单的,目的就是为了暂存信号量最后发出的值。
  • 然后有定义了一个无参闭包
    onBothValue, 而这个闭包体中所做的事情是像新生成的合并信号量发送合并后的元组消息。这样,与新信号量所关联的观察者Observer就会收到这个元组。
  • 紧接着就是创建了一个新的代理观察者observerDelegate, 用来代理新信号量的
    Observer来发送各种事件。而这个
    observerDelegate代理观察者是代替合并后的新信号量发送事件的。
  • 最后要做的就是将
    observerDelegate与要合并的两个信号量进行整合关联,使得要合并的两个信号量中的任何一个信号量发出事件时。在两者都有
    LatestValue的情况下,这个新合并的信号量所绑定的观察者都可以接收到该事件。

具体代码如下所示:

  

 

下方这个方法就负责将新的信号量的发送事件的Observer与之前信号量进行整合。具体做法就是往之前的信号量的Bag容器中添加一个新的观察者Observer,在这个新的观察者处理Event事件时,调用ObserverDelegate的相关事件即可。

  

 

在上述代码中,我们对暂存之前两个信号量最后发出的值的signalStateotherState进行了相关信息的打印。先打印了hashValue,然后打印了其暂存的值。当着两个对象中的latestValue皆不为空时,那么就调用observerDelegatesendValue方法执行onBothValue闭包,向合并信号量所有的Observer发送元组消息即可

下方就是对signalState和otherState的相关信息进行的打印 ,从打印信息中我们可以看出,尽管在observerWithState()函数中是以参数的形式获取的signalState和otherState,但是其内存地址是不变的,独一份。而且当这两个都有lastestValue的情况下,合并信号量的观察者才会收到相应的Value事件。具体如下所示。

  

 

 

 三、Latest合并原理图

针对上述的代码实现,以及参考之前博客中原理图的形式,于是乎我们给出了下方的这个原理图。原理图应该是清晰明了,一目了然的,在此就不做过多的赘述了。通过下图的结构,我们不难看出,combineLatestSignal信号量仍然是可以进行链式发展的。

 

 

在Signal.swift文件中关于SignalProtocol的扩展的方法中,基本上是按照上述的套路来扩展的。大体就是一个方法返回一个新的信号量,这个新的信号量与原始信号量间通过桥接信号量来进行关联。不同的方法在处理原信号量往新的信号量发送事件时,在中间所做的事情不同。Signal.swift文件中还有好多类似的方法,在此就不一一进行介绍了,如果你对某个方法的实现感兴趣,可以采用上述的套路来进行解析。

今天的博客就先到这儿,下篇博客我们会继续解析ReactiveSwift框架中的其他内容。

上述代码github分享地址:

转载地址:http://zazix.baihongyu.com/

你可能感兴趣的文章
国内先进的智能移动广告聚合平台-KeyMob聚合
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
PHP - 如何打印函数调用树
查看>>
js闭包
查看>>
寒假。3.3.G - Common Child (最大公共子序)
查看>>
设计模式学习笔记--原型模式
查看>>
.Net 通过MySQLDriverCS操作MySQL
查看>>
JS Cookie
查看>>
ubuntu Unable to locate package sysv-rc-conf
查看>>
笔记:认识.NET平台
查看>>
cocos2d中CCAnimation的使用(cocos2d 1.0以上版本)
查看>>
【吉光片羽】短信验证
查看>>
MacBook如何用Parallels Desktop安装windows7/8
查看>>
gitlab 完整部署实例
查看>>
GNS关于IPS&ASA&PIX&Junos的配置
查看>>
七天学会ASP.NET MVC (四)——用户授权认证问题
查看>>
upgrade to iOS7,how to remove stroyboard?
查看>>
影响企业信息化成败的几点因素
查看>>
SCCM 2016 配置管理系列(Part8)
查看>>