RxSwift-Driver探究(三)

Driver

Driver是RxSwift里的一个高阶函数,一般我们会在发送网络请求时,将请求后的数据drive到我们想要绑定的UI序列中,为什么要使用Driver呢?Driver又是什么呢?我们一起来看下它的底层实现。

请看源码:

  let result  = inputTF.rx.text.orEmpty
            .asDriver()
            .flatMap {
                return self.dealwithData(inputText: $0)
                    .asDriver(onErrorJustReturn: "检测到了错误事件")
            }
        // 请求一次网络
        // 绑定到了UI - 主线程
        // titlt - 非error
        result.map { "长度: \(($0 as! String).count)"}.drive(self.textLabel.rx.text)
      
        result.map { "\($0 as! String)"}
            .drive(self.btn.rx.title())
 func dealwithData(inputText:String)-> Observable{
        print("请求网络了 \(Thread.current)") // data
        return Observable.create({ (ob) -> Disposable in
            if inputText == "1234" {
                ob.onError(NSError.init(domain: "com.lgcooci.cn", code: 10086, userInfo: nil))
            }// json  - model username pasword
            // username passopp - lgError  - 8001 - httpCoder 100 - 500
            // 封装 vm - error -
            DispatchQueue.global().async {
                print("发送之前看看: \(Thread.current)")
                ob.onNext("已经输入:\(inputText)")
                ob.onCompleted()
            }
            return Disposables.create()
        })
    }
  • 我们模拟一个需求,假设当我们在textField中输入1个字符就向服务器发送一次请求dealwithData(inputText:String)->Observable假设在请求完数据后在异步通过观察者ob调用onNext函数发送给订阅者。
    *onErrorJustReturn :这个方法可以将error错误转化为onNext事件。
    *dirve将响应序列绑定到UI序列上。

在这里我们就有疑问了,既然是在异步发送响应,那么我们帮的UI序列时怎么没有在主线程里做绑定呢?那当然就是Driver老司机的功劳啦。我们现在开始点进去看看Driver老司机就近做了什么骚操作。

Driver的初始化

extension ControlProperty {
    /// Converts `ControlProperty` to `Driver` trait.
    ///
    /// `ControlProperty` already can't fail, so no special case needs to be handled.
  //ControlProperty已经不能失败,所以不需要处理任何特殊情况。
    public func asDriver() -> Driver {
        return self.asDriver { _ -> Driver in
            #if DEBUG
                rxFatalError("Somehow driver received error from a source that shouldn't fail.")
            #else
                return Driver.empty()
            #endif
        }
    }
}
  • asDriver()ControlProperty结构体的拓展,他的返回值为self.asDriver的闭包
public typealias Driver = SharedSequence
  • 再点击Driver后我们发现他是SharedSequence的一个别名,我们把它称为共享序列
public struct SharedSequence : SharedSequenceConvertibleType {
    let _source: Observable

    init(_ source: Observable) {
        self._source = SharingStrategy.share(source)
    }
}
  • Driver初始化时,_source属性保存了SharingStrategy.share(source)产生的可观察序列
public struct DriverSharingStrategy: SharingStrategyProtocol {
    public static var scheduler: SchedulerType { return SharingScheduler.make() }
    public static func share(_ source: Observable) -> Observable {
        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在初始化的时候,它的子类初始化时将scheduler 调度器设置在了主队列上

为什么要使用Driver?

(1)Driver最常使用的场景应该就是需要用序列来驱动应用程序的情况了,比如:
* 通过 CoreData 模型驱动UI
* 使⽤一个UI 元素值(绑定)来驱动另一个UI元素值
(2)与普通的操作系统驱动程序⼀一样,如果出现序列列错误,应用程序将停⽌响应用户输入。
(3)在主线程上观察到这些元素也是极其重要的,因为UI元素和应用程序逻辑通常不是线程安全的。
(4)此外,使用构建 Driver 的可观察的序列列,它是共享状态变化。
(5)Driver可以说是最复杂的trait,它的目标是提供一种简便的方式在 UI 层编写响应式代码。
(6)如果我们的序列满足如下特征,就可以使用它:
• 不会产生 error 事件
• 一定在主线程监听(MainScheduler)
• 共享状态变化(shareReplayLatestWhileConnected)

你可能感兴趣的:(RxSwift-Driver探究(三))