什么是Driver
Driver
的出现是为了让我们在写UI层的响应式代码的时候更加直观。
为什么它的名字叫Driver
?它意图更好的通过数据去驱动我们的应用程序。
比如:
- 从数据模型去驱动UI
- 使用其它UI元素的值去驱动UI
- …….
在正常开发中,由于用户操作导致错误发生可能会使我们的应用程序崩溃。
由于UI元素操作通常不是线程安全的,要保证在主线程操作。
或者某个序列在有多个订阅者者时只需要shareReplay(1)
。
经典例子
先来看一下经典的例子,看看我们在正常的开发中可能会写出如下的代码:
1 | let results = query.rx.text |
这段代码的意图是:
- 对用户的输入进行节流
- 每次查询连接服务器搜索结果
- 绑定结果到UI结果
我们来看看这段代码有什么问题?
- 如果
fetchAutoCompleteItems
发生了错误,网络错误或者解析出错,这个错误会导致取消所有绑定,UI界面也不会更新新的结果。 - 如果
fetchAutoCompleteItems
在后台线程返回了结果,结果可能会在后台线程绑定到UI界面,这样会导致不确定的崩溃。 - 结果绑定到了两个UI元素,意味着,每次用户搜索,会发送2次请求,这不是我们想要的行为。
所以规范一点的写法应该是这样:
1 | let results = query.rx.text |
要保证这些所有的情况都被处理在大的系统里面是很难的,这里有一种简单的方法哪就是使用Driver
。来看下下面的例子:
1 | let results = query.rx.text.asDriver() // This converts a normal sequence into a `Driver` sequence. |
Driver特性
上面改进后的版本发生了什么?首先第一个asDriver
把ControlProperty
对象转换成了Driver
对象。
1 | query.rx.text.asDriver() |
Driver
拥有ControlProperty
的所有属性,其实它是在上面包了一层。
第二个改变的地方是:
1 | .asDriver(onErrorJustReturn: []) |
任何的可被观察的序列都能转成Driver
,只要满足以下3点:
- 不能抛出错误
- 订阅在主线程
- 多个订阅者
shareReplay(1)
asDriver(onErrorJustReturn: [])
其实等同于:
1 | let safeSequence = xs |
最后一点就是使用drive
代替bindTo
。
所以下面的代码:
1 | let intDriver = sequenceOf(1, 2, 3, 4, 5, 6) |
等价:
1 | let intObservable = sequenceOf(1, 2, 3, 4, 5, 6) |
总结
通过例子,大家也看到了什么时候应该使用Driver
,如果你的代码需要满足上面三种情况的话,那么你可以使用Driver
。否则如果你要多次切换线程、自己捕获传递错误、或者其它,可以仍用Observable
。
大家试着把上一篇讲的注册项目改成Driver
。
然后参考Driver
的版本: