天天看點

RxSwift Scheduler排程環境RxSwift Scheduler排程環境

RxSwift Scheduler排程環境

排程環境的初探

DispatchQueue.global().async {
   self.button.rx.tap.subscribe(onNext: { () in
        print("訂閱回調線程 \(Thread.current)") // 主線程
   }).disposed(by: self.disposeBag)
}
           

上面按鈕的點選事件回調線程為主線程,這一過程是如何實作的呢?明明是在子線程中訂閱的。且看源碼分析。

RxSwift Scheduler排程環境RxSwift Scheduler排程環境

高清無碼Xmind下載下傳位址

public var tap: ControlEvent<Void> {
    return controlEvent(.touchUpInside)
}
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)
}

           

1、self.button.rx.tap建立了一個序列傳回的是ControlEvent結構體,它實作了ControlEventType協定,而ControlEventType又實作了ObservableType協定。在controlEvent方法中并沒有對線程進行過操作

2、而MainScheduler.ensureRunningOnMainThread()隻是判斷目前執行的是否是主線程

3、下面來看ControlEvent的初始化方法

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

由源碼可知,唯一有線程操作的地方是ConcurrentMainScheduler.instance

private init(mainScheduler: MainScheduler) {
    self._mainQueue = DispatchQueue.main
    self._mainScheduler = mainScheduler
}
public static let instance = ConcurrentMainScheduler(mainScheduler: MainScheduler.instance)
           

在ConcurrentMainScheduler初始化方法中預設建立了一個主隊列

4、這裡events = source, 由controlEvent方法中建立傳遞過來的,events.subscribeOn()就決定了訂閱在主線程中了。