RxSwift中的老司机
使用可观察序列的流程
Observable生成可观察序列- 如果需要变换处理可观察序列通过高阶函数处理成新的可观察序列
subscribe订阅onNext,onError,onComplete处理
但是当面对多线程和UI处理的可观察序列就可能处出现问题,举个🌰
- 模拟请求接口查询数据
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.lgcooci.cn", code: 10086, userInfo: nil))
}
DispatchQueue.global().async {
print("发送之前看看: \(Thread.current)")
ob.onNext("已经输入:\(inputText)")
ob.onCompleted()
}
return Disposables.create()
})
}
- 通过可观察序列监听
let result = inputTF.rx.text.skip(1).flatMap { [weak self](input) -> Observable<Any> in
return (self?.dealwithData(inputText: input ?? ""))!
}
- 订阅可观察序列
//第一次订阅
result.subscribe { (even) in
print(even)
print(Thread.current)
}.disposed(by: disposeBag)
//第二次订阅
result.subscribe { (even) in
print(even)
print(Thread.current)
}.disposed(by: disposeBag)
- 运行后在,输入一个1如下:
结果分析
由于我们订阅两次,我们的模拟的请求操作运行了两次,还有就是接收信号的线程在子线程
我们想要得到的结果,是请求操作只运行一次,RxSwift提供了一种共享重复的机制share(Replay:),它会返回一个新的事件序列,它监听底层序列的事件,并且通知自己的订阅者们。
解决有多个订阅者的情况下,map会被执行多次的问题
let result = inputTF.rx.text.skip(1).flatMap { [weak self](input) -> Observable<Any> in
return (self?.dealwithData(inputText: input ?? ""))!
}.share(replay: 1, scope: .whileConnected)
再次运行输入1,运行结果如下
但是,监听到的事件依旧在子线程,解决响应异步是指定监听的执行线程
let result = inputTF.rx.text.skip(1).flatMap { [weak self](input) -> Observable<Any> in
return (self?.dealwithData(inputText: input ?? ""))!
.observeOn(MainScheduler.instance)
}.share(replay: 1, scope: .whileConnected)
再次运行,打印如下
这样我们完美的处理了多次处理和异步响应的问题,但是确实增加了不少工作量,但是这也是应该带需要处理的是,那么有没有更简单更快捷的开发使用方式呢,那么老司机出现了
Driver的介绍和原理
介绍
Driver提供了一种在UI层编程响应式的简单的方式- 使用它的满足条件
- 不会产生error事件
- 在主线程监听事件
- 共享状态变化
老司机的优势
- 数据驱动UI
- 停止响应错误事件
- 一定要在主线程处理如UI等逻辑
- 共享状态变化
原理
extension ControlProperty {
public func asDriver() -> Driver<Element> {
return self.asDriver { _ -> Driver<Element> in
#if DEBUG
rxFatalError("Somehow driver received error from a source that shouldn't fail.")
#else
return Driver.empty()
#endif
}
}
}
public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>
代码分析
asDriver()是ControlProperty结构体的extension,他的返回值为self.asDriver的闭包,而Driver是ShareSequence的别名,ShareSequence叫做共享序列
共享序列的实现
public struct DriverSharingStrategy: SharingStrategyProtocol {
public static var scheduler: SchedulerType { return SharingScheduler.make() }
public static func share<Element>(_ source: Observable<Element>) -> Observable<Element> {
return source.share(replay: 1, scope: .whileConnected)
}
}
public enum SharingScheduler {
/// Default scheduler used in SharedSequence based traits.
public private(set) static var make: () -> SchedulerType = { MainScheduler() }
}
public final class MainScheduler : SerialDispatchQueueScheduler {
private let _mainQueue: DispatchQueue
/// Initializes new instance of `MainScheduler`.
public init() {
self._mainQueue = DispatchQueue.main
super.init(serialQueue: self._mainQueue)
}
}
注意以上Driver的构造器,将调度指定在主线程