使用 Scheduler 来让 Observable 支持多线程。observeOn 指定 Observable 在那个 Scheduler 发出通知
下面让我们一起来看一下observeOn内部是如何实现的
先来看一段简单的代码
Observable.of(1,2,3,4,5,6,7,8,9,10)
.observeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "observeOnSerial"))
.subscribe{print("observeOn",$0,Thread.current)}
.disposed(by: self.bag)
一句一句来解析:
-
(一)Observable.of(1,2,3,4,5,6,7,8,9,10)
public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable<Element> {
return ObservableSequence(elements: elements, scheduler: scheduler)
}
这段代码会要求我们传入一些元素,然后会给一个默认的scheduler:CurrentThreadScheduler
会返回一个ObservableSequence类型的序列
final private class ObservableSequence<Sequence: Swift.Sequence>: Producer<Sequence.Element> {
fileprivate let _elements: Sequence
fileprivate let _scheduler: ImmediateSchedulerType
init(elements: Sequence, scheduler: ImmediateSchedulerType) {
self._elements = elements
self._scheduler = scheduler
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
该序列初始化时保存了原序列(
elements) 和 调度环境(scheduler),并继承了Producer,实现了run方法。
-
(二).observeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "observeOnSerial"))
public class SerialDispatchQueueScheduler : SchedulerType {
let configuration: DispatchQueueConfiguration
init(serialQueue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) {
self.configuration = DispatchQueueConfiguration(queue: serialQueue, leeway: leeway)
}
public convenience init(internalSerialQueueName: String, serialQueueConfiguration: ((DispatchQueue) -> Void)? = nil, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) {
let queue = DispatchQueue(label: internalSerialQueueName, attributes: [])
serialQueueConfiguration?(queue)
self.init(serialQueue: queue, leeway: leeway)
}
}
使用便利构造器初始化一个串行队列,并调用
self.init将队列queue和 延迟时间leeway保存在self.configuration中。
接下来,会带着创建好的队列来到 observeOn 函数:
public func observeOn(_ scheduler: ImmediateSchedulerType)
-> Observable<Element> {
if let scheduler = scheduler as? SerialDispatchQueueScheduler {//串行
return ObserveOnSerialDispatchQueue(source: self.asObservable(), scheduler: scheduler)
}
else {//并发
return ObserveOn(source: self.asObservable(), scheduler: scheduler)
}
}
由于我们创建的是串行队列,所以走上面对方法:
final private class ObserveOnSerialDispatchQueue<Element>: Producer<Element> {
let scheduler: SerialDispatchQueueScheduler
let source: Observable<Element>
init(source: Observable<Element>, scheduler: SerialDispatchQueueScheduler) {
self.scheduler = scheduler//<SerialDispatchQueueScheduler: 0x600003329b90>
self.source = source//ObservableSequence<Array<Int>
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = ObserveOnSerialDispatchQueueSink(scheduler: self.scheduler, observer: observer, cancel: cancel)
let subscription = self.source.subscribe(sink)
return (sink: sink, subscription: subscription)
}
}
ObserveOnSerialDispatchQueue在初始化的时候保存了源函数(Observable.of(1,2,3,4,5,6,7,8,9,10))和我们初始化的串行队列(SerialDispatchQueueScheduler),并且同样继承了Producer,实现了自己的run方法。
-
(三).subscribe{print("observeOn",$0,Thread.current)}
这步是由源序列经过observeOn方法后会返回的ObserveOnSerialDispatchQueue来进行订阅的。
因为 ObserveOnSerialDispatchQueue 继承于producer,子类没有的会找父类,所以会来到Producer的subscribe:
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {//当前线程被绑定
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
由pthread_getspecific(CurrentThreadScheduler.isScheduleRequiredKey) == nil返回为 true可知当前线程没有被绑定,走else方法。
然后携带闭包来到当前调度环境的schedule方法
public func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
if CurrentThreadScheduler.isScheduleRequired {//没有绑定线程
CurrentThreadScheduler.isScheduleRequired = false //走set方法 绑定一个
let disposable = action(state)//state 外界闭包
defer {//延长执行 所有事务执行之后将调度环境置nil
CurrentThreadScheduler.isScheduleRequired = true
CurrentThreadScheduler.queue = nil
}
guard let queue = CurrentThreadScheduler.queue else {
return disposable
}
while let latest = queue.value.dequeue() {
if latest.isDisposed {
continue
}
latest.invoke()
}
return disposable
}
let existingQueue = CurrentThreadScheduler.queue
let queue: RxMutableBox<Queue<ScheduledItemType>>
if let existingQueue = existingQueue {//当前线程存在队列,赋值
queue = existingQueue
}
else {//当前线程不存在队列,初始化一个
queue = RxMutableBox(Queue<ScheduledItemType>(capacity: 1))
CurrentThreadScheduler.queue = queue
}
let scheduledItem = ScheduledItem(action: action, state: state)
queue.value.enqueue(scheduledItem)
return scheduledItem
}
CurrentThreadScheduler.isScheduleRequired = false通过isScheduleRequired的set方法将当前的线程调度环境进行了绑定。然后会走let disposable = action(state)外界带过来的闭包。
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
self.run 会回到子类的run方法中,就会回到ObserveOnSerialDispatchQueue的run方法中
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = ObserveOnSerialDispatchQueueSink(scheduler: self.scheduler, observer: observer, cancel: cancel)
let subscription = self.source.subscribe(sink)
return (sink: sink, subscription: subscription)
}
带着observer:<AnonymousObserver<Int>: 0x600003329dd0>和scheduler:<SerialDispatchQueueScheduler: 0x600003329b90>来进行sink的初始化。
final private class ObserveOnSerialDispatchQueueSink<Observer: ObserverType>: ObserverBase<Observer.Element> {
let scheduler: SerialDispatchQueueScheduler
let observer: Observer
let cancel: Cancelable
var cachedScheduleLambda: (((sink: ObserveOnSerialDispatchQueueSink<Observer>, event: Event<Element>)) -> Disposable)!
init(scheduler: SerialDispatchQueueScheduler, observer: Observer, cancel: Cancelable) {
self.scheduler = scheduler//<SerialDispatchQueueScheduler: 0x600003329b90>
self.observer = observer//<AnonymousObserver<Int>: 0x600003329dd0>
self.cancel = cancel
super.init()
self.cachedScheduleLambda = { pair in
guard !cancel.isDisposed else { return Disposables.create() }
pair.sink.observer.on(pair.event)
if pair.event.isStopEvent {
pair.sink.dispose()
}
return Disposables.create()
}
}
override func onCore(_ event: Event<Element>) {
_ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!)
}
初始化完成后会以sink为参数进行订阅let subscription = self.source.subscribe(sink)
由上面可以知道self.source为之前保存的源序列ObservableSequence进行订阅,由于 ObservableSequence也继承于Producer,所以又会来到Producer的subscribe(第一次订阅是ObserveOnSerialDispatchQueue,这次是ObservableSequence)
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {//当前线程被绑定
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
上次ObserveOnSerialDispatchQueue订阅时,已经绑定线程(CurrentThreadScheduler.isScheduleRequired = false),所以会走if的方法,self.run 会来到源序列 ObservableSequence的run方法.
final private class ObservableSequence<Sequence: Swift.Sequence>: Producer<Sequence.Element> {
fileprivate let _elements: Sequence
fileprivate let _scheduler: ImmediateSchedulerType
init(elements: Sequence, scheduler: ImmediateSchedulerType) {
self._elements = elements//1 2 3 4 5 6 7 8 9 10
self._scheduler = scheduler//<CurrentThreadScheduler: 0x600003f681a0>
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
携带参数observer(<ObserveOnSerialDispatchQueueSink<AnonymousObserver>: 0x600001941980>)来到sink的初始化方法,super.init将observer保存,接下来会走sink.run
final private class ObservableSequenceSink<Sequence: Swift.Sequence, Observer: ObserverType>: Sink<Observer> where Sequence.Element == Observer.Element {
typealias Parent = ObservableSequence<Sequence>
private let _parent: Parent
init(parent: Parent, observer: Observer, cancel: Cancelable) {
self._parent = parent//<ObservableSequence<Array<Int>>: 0x600002835740>
super.init(observer: observer, cancel: cancel)//<ObserveOnSerialDispatchQueueSink<AnonymousObserver<Int>>: 0x600001941980>
}
func run() -> Disposable {
return self._parent._scheduler.scheduleRecursive(self._parent._elements.makeIterator()) { iterator, recurse in
var mutableIterator = iterator
if let next = mutableIterator.next() {
self.forwardOn(.next(next))
recurse(mutableIterator)
}
else {
self.forwardOn(.completed)
self.dispose()
}
}
}
}
- 这里返回的
self._parent为<ObservableSequence<Array<Int>>: 0x600002835740>self._parent._scheduler为ObservableSequence的_scheduler,也就是一开始我们创建序列是给的默认当前线程<CurrentThreadScheduler: 0x600003f681a0>
接下来 要来到CurrentThreadScheduler的scheduleRecursive方法,然而并没有,由于CurrentThreadScheduler继承ImmediateSchedulerType,所以来到ImmediateSchedulerType的scheduleRecursive方法中
public func scheduleRecursive<State>(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> Void) -> Void) -> Disposable {
let recursiveScheduler = RecursiveImmediateScheduler(action: action, scheduler: self)
recursiveScheduler.schedule(state)
return Disposables.create(with: recursiveScheduler.dispose)
}
将外面穿进来的 state(源序列的迭加器IndexingIterator<Array<Int>>)和逃逸闭包,self 为CurrentThreadScheduler传进来做参数,进行RecursiveImmediateScheduler的初始化 ,然后调用schedule方发,里面会有一些🔒之类的,有一句比较核心
if let action = action {
action(state, self.schedule)
}
现在开始会往回执行action(state, self.schedule)会回到ObservableSequenceSink中run方法的闭包中
var mutableIterator = iterator
if let next = mutableIterator.next() {
self.forwardOn(.next(next))
recurse(mutableIterator)
}
else {
self.forwardOn(.completed)
self.dispose()
}
这个迭代器包括所有的元素,和当前位置position,如果有下一个接着递归调用,没有就发送完成事件。
self.forwardOn 回来到 sink的forwardOn调用self._observer.on 而 self._observer 就是之前保存的<ObserveOnSerialDispatchQueueSink<AnonymousObserver<Int>>: 0x600001941980> 所以接下来会走ObserveOnSerialDispatchQueueSink 的 onCore 方法
override func onCore(_ event: Event<Element>) {
_ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!)
}
self.scheduler.schedule 也就是SerialDispatchQueueScheduler 的 schedule
public final func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
return self.scheduleInternal(state, action: action)
}
func scheduleInternal<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
return self.configuration.schedule(state, action: action)
}
执行事件next(1)和 cachedScheduleLambda 的逃逸闭包将作为参数,传到
SerialDispatchQueueScheduler 初始化时保存self.configuration的schedule方法中
func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
let cancel = SingleAssignmentDisposable()
self.queue.async {
if cancel.isDisposed {
return
}
cancel.setDisposable(action(state))
}
return cancel
}
在
observeOn中创建的队列异步执行闭包(ObserveOnSerialDispatchQueueSink中的cachedScheduleLambda),也就是观察者的回调。 然后会带着我们创建的队列和事件(pair)回到闭包中:
self.cachedScheduleLambda = { pair in
guard !cancel.isDisposed else { return Disposables.create() }
pair.sink.observer.on(pair.event)
if pair.event.isStopEvent {
pair.sink.dispose()
}
return Disposables.create()
}
然后调用pair.sink也就是ObserveOnSerialDispatchQueueSink的observer.on方法(print("observeOn",$0,Thread.current))
最后方法层层回收,一直到递归结束,发送completed事件
return self._parent._scheduler.scheduleRecursive(self._parent._elements.makeIterator()) { iterator, recurse in
var mutableIterator = iterator
if let next = mutableIterator.next() {
self.forwardOn(.next(next))
recurse(mutableIterator)
}
else {
self.forwardOn(.completed)
self.dispose()
}
}
总结
调度器Scheduler是对线程进行了封装,
subscribeOn操作符,不是用源序列直接订阅,而是封装了中间层sink,让源序列的元素在特定的队列中发出通知(pair.sink.observer.on(pair.event))。