这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
前言
在上面几节中,我主要讲解了了Observable(序列)。
其中我将序列从代码和工控的角度进行了分析,将序列比作是流水线,我个人觉得是个一个生动鲜活的例子,并且对于我对Rx的理解起到了很重要的效果。
这次所讲到的Observer (观察者)我也将继续延续从工控角度的进行讲解与说明。
什么是Observer(观察者)
如果说序列是流水线的话,流水线的核心功能就是运输物品,从工控的角度看,这个叫做输出
。
序列可以通过其定义的构建函数,将物品源源不断的输出
,但凡有物品输出,就会有接受这些物品的地方。
而接受这些物品的地方,我们其实就可以称之为——Observer (观察者)。
理解Observer(观察者)
在之前的文章中,就有掘友吐槽说Rx的这个Observable和Observer的命名,就很多让人造成歧义,非常不便于理解。
其实我觉得这种不易理解,是文化与母语差异造成的,就好比中文里,其实可以使用把
和被
两种不同的风格说明同样一件事情一样。
而写RxSwift框架的大佬一般都是以英文语义着手的,所以确实饶了一点。
不过如果我们从输出
和输入
角度看问题的话,就简单多了。
一个Rx的事件,必然是从事件源开始的,也就是说,必须先产生Observable(序列),并且作为输出端进行输出。
Observer (观察者)作为接受端,将序列作为自己的输入,传递过来。
这也就RxSwift中文文档举的几个例子一样:
-
当《海贼王》更新一集时,我们就立即观看这一集
观看这一集就是观察者
Observer<OnePieceEpisode>
。
序列自己是不会做事情的,它只是忠于自己的职责,将事件一个接一个传递过来,而决定做什么,该怎么做的,就是观察者。
如果说序列是流水线,那么观察者就是传感器:
传感器(英文名称:transducer/sensor)是一种检测装置,能感受到被测量的信息,并能将感受到的信息,按一定规律变换成为电信号或其他所需形式的信息输出,以满足信息的传输、处理、存储、显示、记录和控制等要求。
使用Observer(观察者)
一般我们在序列后面追加的subscribe
中的实现,实际上已经就是Observer(观察者)了。
下面这段代码,一个手势的点击事件,并且实现点击后运行的效果。
我们完全可以理解为:
手势点击(输出)->subscribe(输入,实现print方法)
let tap = UITapGestureRecognizer()
view.addGestureRecognizer(tap)
tap.rx.event
.subscribe { _ in
print("tap的点击事件")
}.disposed(by: rx.disposeBag)
复制代码
其实上面这段代码还可以这么写:
/// 初始化点击事件并添加手势到view
let tap = UITapGestureRecognizer()
view.addGestureRecognizer(tap)
/// 观察者
let observer: AnyObserver<UITapGestureRecognizer> = AnyObserver { (_) in
print("tap的点击事件")
}
/// tap点击作为输出
tap.rx.event
/// 绑定到观察者
.subscribe(observer)
.disposed(by: rx.disposeBag)
复制代码
虽然从书写与可读性上,我会使用第一种方式,但是对于本节的理解第二种方式更适合。
AnyObserver与Binder
其实说白了就是两个不同类型的观察者啦。
如果你不知道用什么作为观察者的时候,就使用了AnyObserver。
你只用记住,Binder的这些特征:
- 不会处理错误事件
- 确保绑定都是在给定Scheduler上执行(默认 MainScheduler)
一旦产生错误事件,在调试环境下将执行 fatalError
,在发布环境下将打印错误信息。
AnyObserver可用于多种场合,而Binder一般用的UI组件的绑定工作。
总结
本节主要讲解了Observable(序列)对应的Observer(观察者)。
通过将Observer(观察者)类比为工控的传感器,通过输出与输入来说明调用。
Observer(观察者)有两个选型,AnyObserver与Binder,注意它们的使用场景。
下一节预告
从我个人阅读代码来看,Observer (观察者)在iOS中用的最多的是其中的Binder,在RxCocoa的源代码中的很多参数都是通过其进行的属性绑定。
很大一部分原因,是因为在有些场景非常特别,它们既是可监听序列也是观察者。
这就是我们下一节的内容。
参考文档
RxSwift编写wanandroid客户端现已开源
目前RxSwift编写wanandroid客户端已经开源了——项目链接。
我进行了一轮CodeReview,并增加了一些小功能:
-
添加了iOS的黑暗模式适配
-
上拉加载更多使用了无感知功能
-
MBProgressHUD替换为SVProgressHUD
记得给个star喔!
附上一张效果图片: