RxSwift 调度者-scheduler(一)

753 阅读2分钟

RxSwift篇章

一:案例

        DispatchQueue.global().async {
            self.button.rx
                .tap
                .subscribe(onNext: { () in
                    print("点击了按钮 --- \(Thread.current)")
                })
                .disposed(by: self.disposeBag)
        }

  • 运行答案是主线程
  • 问: 当前子线程是如何切换到主线程的?

二:源码分析

创建序列

  • 点击tap跟踪
    public func controlEvent(_ controlEvents: UIControl.Event) -> ControlEvent<()> {
        let source: Observable<Void> = Observable.create { [weak control = self.base] observer in
        // 调度主线程判断
                MainScheduler.ensureRunningOnMainThread()
                guard let control = control else {
                    observer.on(.completed)
                    return Disposables.create()
                }

                let controlTarget = ControlTarget(control: control, controlEvents: controlEvents) { _ in
                    observer.on(.next(()))
                }

                return Disposables.create(with: controlTarget.dispose)
            }
            .takeUntil(deallocated)

        return ControlEvent(events: source)
    }
  • 序列sorce创建
  • 内部主线程判断, 只有为主线程下面代码才执行.
  • ControlTarget点击响应observer.on(.next(())),最后定位到takeUntil类型.下面简称源序列.
  • 进入ControlEvent序列
//
    public init<Ev: ObservableType>(events: Ev) where Ev.Element == Element {
        self._events = events.subscribeOn(ConcurrentMainScheduler.instance)
    }
//ConcurrentMainScheduler
public final class ConcurrentMainScheduler : SchedulerType {
    /// - returns: Current time.
    public var now: Date {
        return self._mainScheduler.now as Date
    }

    private init(mainScheduler: MainScheduler) {
        self._mainQueue = DispatchQueue.main
        self._mainScheduler = mainScheduler
    }
}
  • 源序列events.subscribeOn执行了subscribeOn函数.

  • ConcurrentMainScheduler,内部封装了主队列

  • 字面理解,出现了subscribeOn订阅在..., Scheduler(关键字,况且包含主队列), 看到这里就应该划重点了吧.

  • subscribeOn做了什么?

// 进入subscribeOn
    public func subscribeOn(_ scheduler: ImmediateSchedulerType)
        -> Observable<Element> {
        return SubscribeOn(source: self, scheduler: scheduler)
    }

// SubscribeOn序列
final private class SubscribeOn<Ob: ObservableType>: Producer<Ob.Element> {
    init(source: Ob, scheduler: ImmediateSchedulerType) {
        self.source = source
        self.scheduler = scheduler
    }
    
    override func run()...{
        let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel)
        let subscription = sink.run()
        return (sink: sink, subscription: subscription)
    }
}
  • SubscribeOn为序列
  • 内部保存了源序列和scheduler.
  • ControlEvent 中的self._events保存了这个序列.

订阅序列

  • 进入.subscribe查看: 这里为controlEvent.
    /// - returns: `Observable` interface.
    public func asObservable() -> Observable<Element> {
        return self._events
    }
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        return self._events.subscribe(observer)
    }
  • self._events 就是subscribeOn序列,执行订阅.
  • 订阅的流程肯定会来到sink, 这里为 SubscribeOnSink, 进入 run().
final private class SubscribeOnSink {

    func run() -> Disposable {
        let disposeEverything = SerialDisposable()
        let cancelSchedule = SingleAssignmentDisposable()
        disposeEverything.disposable = cancelSchedule
        //
        let disposeSchedule = self.parent.scheduler.schedule(()) { _ -> Disposable in
            let subscription = self.parent.source.subscribe(self)
            disposeEverything.disposable = ScheduledDisposable(scheduler: self.parent.scheduler, disposable: subscription)
            return Disposables.create()
        }
        ...
        return disposeEverything
    }
}
    public func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        if DispatchQueue.isMain {
            return action(state)
        }

        let cancel = SingleAssignmentDisposable()

        self._mainQueue.async {
            if cancel.isDisposed {
                return
            cancel.setDisposable(action(state))
        }

        return cancel
    }
  • 重点self.parent.scheduler.schedule(())
  • self.parent.scheduler, 这里的scheduler为 ConcurrentMainScheduler.
  • 在schedule 函数里,self._mainQueue.async 进入主线程,其中action(state)返回schedule传入的闭包.
  • 闭包内self.parent.source.subscribe(self)执行源序列的订阅.
  • 随着订阅的流程直到源序列的创建闭包传入observer执行,其内部为主线程的判断我们可以肯定为主线程了.

总结

整体流程看起是比较复杂,但是我们可以分析出:

  • 源序列的包装.
  • 内部序列的创建.
  • 源序列的调度环境.