美文网首页
RXSwift中Scheduler调度者本质核心原理解析(一)

RXSwift中Scheduler调度者本质核心原理解析(一)

作者: lb_ | 来源:发表于2019-08-04 13:02 被阅读0次

    在之前我们看 RxSwift 源码时,经常看到一个 Scheduler ,但是没有去管他, 其实 SchedulerRxSwift 针对多线程的一套封装, 大部分是使用 GCD ,另外还有部分是 Operation . 目的是为了让用户更直接了当的决定在哪一个队列中去异步执行观察/订阅.

    先来看一个例子:

    DispatchQueue.global().async {
        print("请求数据\(Thread.current)")
        self.actionBtn.rx.tap
            .subscribe(onNext: { () in
               print("tap =--- \(Thread.current)")
        })
    }
    

    问: 在按钮点击后打印结果是在哪个线程?

    打印结果如下:

    请求数据<NSThread: 0x60000241d440>{number = 3, name = (null)}
    tap =--- <NSThread: 0x60000244d980>{number = 1, name = main}
    

    问题:
    为什么我们在子线程对 tap 序列订阅, 执行响应时会自动回到主线程呢?

    ControlEvent 默认调度解析:

    cmd + 点击 .tap

    extension Reactive where Base: UIButton {
        /// Reactive wrapper for `TouchUpInside` control event.
        public var tap: ControlEvent<Void> {
            return controlEvent(.touchUpInside)
        }
    }
    

    return 了一个 controlEvent , 继续点击 controlEvent.


    发现一个疑似调度者处理的东西, 再点进去 .ensureRunningOnMainThread()
    public class func ensureRunningOnMainThread(errorMessage: String? = nil) {
        #if !os(Linux) // isMainThread is not implemented in Linux Foundation
           guard Thread.isMainThread else {
                rxFatalError(errorMessage ?? "Running on background thread.")
            }
        #endif
    }
    

    发现啥也没干, 没在主线程执行就提示了一句. 好吧.

    那说明在 执行序列创建闭包调用 之前,就已经回到主线程了.
    通过之前核心逻辑分析经验,我们知道 序列创建闭包调用 是在订阅之后执行的.

    也就是说 .tap 返回了一个 ControlEvent 的序列, 而且ControlEvent 并非继承自 Producer , 那么 ControlEvent 必然自己实现了 subscribe 方法, 那么这个序列在订阅时就来到了如下方法:

    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
       return self._events.subscribe(observer)
    }
    

    其中 self. _events 是谁? 我们看下 init 方法

    public init<Ev: ObservableType>(events: Ev) where Ev.Element == Element {
       self._events = events.subscribeOn(ConcurrentMainScheduler.instance)
    }
    

    先不管 subscribeOn 下一篇文章我会讲解, 意思就是在指定队列订阅, 并且返回一个新序列. 那么我们 cmd + ConcurrentMainScheduler

    看init方法

    private init(mainScheduler: MainScheduler) {
        self._mainQueue = DispatchQueue.main
        self._mainScheduler = mainScheduler
    }
    

    至此, ControlEvent 类型序列在默认调度时流程解析完毕, rx 在处理该类型序列的订阅时 , 默认执行在主队列.

    相关文章

      网友评论

          本文标题:RXSwift中Scheduler调度者本质核心原理解析(一)

          本文链接:https://www.haomeiwen.com/subject/yyoedctx.html