五、Driver
5.1 案例引入
请求一次网络,绑定到UI上
5.1.1 采用Observerable
let result0 = inputTF.rx.text.skip(1)
.flatMap { [weak self](input) -> Observable<Any> in
return (self?.dealwithData(inputText:input ?? ""))!
.observeOn(MainScheduler.instance)
.catchErrorJustReturn("检测到了错误事件")
}.share(replay: 1, scope: .whileConnected)
// share(replay: 1, scope: .whileConnected) 共享状态 确保result被订阅多次时,网络请求只执行一次,不重复执行
// 多次订阅
result0.subscribe(onNext: { (element) in
print("第一次订阅到result0:\(element)")
}).disposed(by: disposeBag)
result0.subscribe(onNext: { (element) in
print("第二次订阅到result0:\(element) - \(Thread.current)")
}).disposed(by: disposeBag)
5.1.2 采用Driver
// 请求一次网络
// 绑定到了UI - 主线程
// titlt - 非error
let result = inputTF.rx.text.orEmpty
.asDriver()
.flatMap {
return self.dealwithData(inputText: $0)
.asDriver(onErrorJustReturn: "检测到了错误事件")
}
result.map { "长度: \(($0 as! String).count)"}
.drive(self.textLabel.rx.text)
.disposed(by: disposeBag)
result.map { "\($0 as! String)"}
.drive(self.btn.rx.title())
.disposed(by: disposeBag)
func dealwithData(inputText:String)-> Observable<Any>{
print("请求网络了 \(Thread.current)") // data
return Observable<Any>.create({ (ob) -> Disposable in
if inputText == "1234" {
ob.onError(NSError.init(domain: "com.pxwx.www", code: 10086, userInfo: nil))
}
DispatchQueue.global().async {
print("发送之前看看: \(Thread.current)")
ob.onNext("已经输入:\(inputText)")
ob.onCompleted()
}
return Disposables.create()
})
}
5.2 老司机是什么
1、Driver 可以说是最复杂的 trait,它的⽬目标是提供一种简便的⽅式在 UI 层编写响应式代码。
2、如果我们的序列列满⾜足如下特征,就可以使⽤用它:
- 不会产⽣生 error 事件
- 一定在主线程监听(MainScheduler)
- 共享状态变化(shareReplayLatestWhileConnected)
5.3 **为什要使用 **Driver?
1)、Driver 最常使⽤用的场景,应该就是需要⽤序列来驱动应⽤程序的情况了,比如:
- 通过 CoreData 模型驱动 UI
- 使⽤用一个 UI 元素值(绑定)来驱动另一个 UI 元素值
2)、与普通的操作系统驱动程序一样,如果出现序列列错误,应用程序将停⽌响应用户输入。
3)、在主线程上观察到这些元素也是极其重要的,因为 UI 元素和应⽤程序逻辑通常不是线程安全的。
4)、此外,使⽤用构建 Driver 的可观察的序列列,它是共享状态变化的。
5.4 基本源码解析
Driver其实就是一个序列的别名,为了方便记忆。
public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>
OK!我们看到了source.share(replay: 1, scope: .whileConnected)
,这样就明白了Driver其实也就是对序列的进一层的封装。