有很多在给人介绍Reactive的几个开源项目(ReactiveCocoa, RxSwift)的使用,我就不想在这个方面写什么了。我是一个实践主义者,所以我从我的角度来谈谈这种方案:解决了什么样的问题,怎么实现的,以及适合应用的场景。同时也加深自己对Reactive的理解。
这里我们来看看是怎么实现的,关于pure function
和monad
的部分我也不准备介绍了,毕竟我在这方面还不是特别熟悉。
signal observer
首先我们来想一下一个最简单信号的流程。当一个信号被订阅时(subscribe),发出信号后会触发订阅者(observer)执行下一步(sendNext)。那么一个最简单的信号(signal)和订阅者(observer)的协议就如下。
1 | protocol Observer { |
那么现在实现一个最简单的UIButton的信号。
1 | class ButtonSignal: Signal { |
然后实现一个最简单的订阅者。
1 | class ButtonObserver: Observer { |
最后连接起来
1 | signal = ButtonSignal(button: button) |
那么问题来了,难道我们要为每个信号都创建一个类吗。当然不是,我们可以创建一个通用的信号和订阅者。
1 | class BlockSignal: Signal { |
同时在使用的过程时通过block来创建具体信号。
1 | signal = BlockSignal(block: { (observer) in |
以上就是最简单的信号量和订阅者实现。这里为了简洁的说明问题,所以没有考虑到内存方面的问题。
dispose
上节说了内存方面的问题。还有一个问题就是如何取消订阅呢。那么这里需要有模块负责释放(dispose)。
那么将接口改为
1 | protocol Disposable { |
实现也按照block形式
1 | class BlockDisposable: Disposable { |
使用时和上面基本一致
1 | signal = BlockSignal(block: { (observer) in |
需要解除订阅的时候
1 | self.disposable = signal?.subscribe(observer!) |
之后
到目前为止,可以说signal-observer部分已经完全实现了。
其中冷信号和热信号也非常简单
1 | protocol Subject: Observer, Signal {} |
Scheduler也比较简单,将执行放到对应的队列中即可。
下篇结合我的角度来聊聊应用场景。