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执行,其内部为主线程的判断我们可以肯定为主线程了.
总结
整体流程看起是比较复杂,但是我们可以分析出:
- 源序列的包装.
- 内部序列的创建.
- 源序列的调度环境.