在日常实践开发中,经常会用到一个高阶函数,就是asDriver,而asDriver函数涉及到一个类——Driver。Driver可以说是最复杂的trait,它的⽬标是提供⼀种简便的方式在UI层编写响应式代码。
如果我们的序列满足如下特征,就可以使⽤它:
(1)不会产生 error 事件;
(2)一定在主线程监听(MainScheduler);
(3)共享状态变化(shareReplayLatestWhileConnected)。
我们来看看满足这些特征的例子:
func search(input: String)-> Observable<String> {
return Observable<String>.create({ (observer) -> Disposable in
DispatchQueue.global().async {
...//假装在子线程进行了耗时的搜索
let result = "返回结果"
observer.onNext(result)
observer.onCompleted()
}
return Disposables.create()
})
}
func test() {
let result = inputTf.rx.changed
.flatMap { [weak self](text) -> Observable<Any> in
//flatMap映射成新序列
return self.search(input: text)
.observeOn(MainScheduler())) //主线程
.catchErrorJustReturn("发生错误") //处理error
}.share(replay: 1, scope: .whileConnected) //共享状态变化
result.bind(to: label.rx.text) //绑定
}
这段代码的意思是,监听输入进行搜索,然后把返回结果显示出来。但是看上去不够简洁,那么我们可以用asDriver
代替:
func testWithDriver() {
let result = inputTf.rx.changed
.asDriver()
.flatMap {
return self.search(input: $0)
.asDriver(onErrorJustReturn: "发生错误")
}
result.drive(label.rx.text)
}
- 来看源码,我们直接抓重点
.asDriver(onErrorJustReturn: "发生错误")
(第一个和第二个.asDriver()
其实都是一个意思)。然后对比一下上面的代码,不难发现:
- 我们继续查看,又发现了:
继续:
-
asDriver
最终就是返回了一个Driver
,然后进行.drive()
(作用相当于.bind(to:)
):
result.drive(label.rx.text)
绑定
绑定
-
asDriver
源码分析重点就是以上这些,详细调用流程太繁琐就没必要继续看了,感兴趣的朋友可以自己继续看。
总的来说,
asDriver
就是帮我们封装了一些我们需要的操作,比如处理error事件,在主线程监听,共享状态变化...
网友评论