RxSwift Scheduler排程環境
排程環境的初探
DispatchQueue.global().async {
self.button.rx.tap.subscribe(onNext: { () in
print("訂閱回調線程 \(Thread.current)") // 主線程
}).disposed(by: self.disposeBag)
}
上面按鈕的點選事件回調線程為主線程,這一過程是如何實作的呢?明明是在子線程中訂閱的。且看源碼分析。
高清無碼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()就決定了訂閱在主線程中了。