08RxSwift的调度者Scheduler

问题:我们在进行网络请求的时候,需要创建一个请求返回的data序列,而这个data是一个耗时的操作,我们需要异步去执行,得到数据后再发送响应,如图:
网络请求data序列

这个时候怎么办呢?这就需要用到我们的调度者。

let dataOB: Observable 

dataOB
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .userInitiated))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { [weak self](data) in
        // 更新UI
    })
    .disposed(by: disposeBag)

我们用 subscribeOn 来决定数据序列的构建函数在哪个 Scheduler 上运行。
在上面的例子中,由于获取 Data 需要花费很长的时间,所以用 subsribeOn 切换到 后台Scheduler 来获取 Data 。这样就可以避免阻塞主线程。
我们用 observeOn 来决定在哪个 Scheduler 监听这个数据序列。
在上面的例子中,通过 observerOn 方法切换到主线程来监听并处理结果。

介绍一下RxSwift中的几种调度器:

MainScheduler

public final class MainScheduler : SerialDispatchQueueScheduler {

    private let _mainQueue: DispatchQueue

    let numberEnqueued = AtomicInt(0)

    /// Initializes new instance of `MainScheduler`.
    public init() {
        self._mainQueue = DispatchQueue.main
        super.init(serialQueue: self._mainQueue)
    }

    /// Singleton instance of `MainScheduler`
    public static let instance = MainScheduler()

    。。。
   
}

super.init里面的方法有一个实现如下

 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)
    }

CurrentThreadScheduler

public class CurrentThreadScheduler : ImmediateSchedulerType {
    typealias ScheduleQueue = RxMutableBox>

    /// The singleton instance of the current thread scheduler.
    public static let instance = CurrentThreadScheduler()

    private static var isScheduleRequiredKey: pthread_key_t = { () -> pthread_key_t in
        let key = UnsafeMutablePointer.allocate(capacity: 1)
        defer { key.deallocate() }
                                                               
        guard pthread_key_create(key, nil) == 0 else {
            rxFatalError("isScheduleRequired key creation failed")
        }

        return key.pointee
    }()

    private static var scheduleInProgressSentinel: UnsafeRawPointer = { () -> UnsafeRawPointer in
        return UnsafeRawPointer(UnsafeMutablePointer.allocate(capacity: 1))
    }()

    static var queue : ScheduleQueue? {
        get {
            return Thread.getThreadLocalStorageValueForKey(CurrentThreadSchedulerQueueKey.instance)
        }
        set {
            Thread.setThreadLocalStorageValue(newValue, forKey: CurrentThreadSchedulerQueueKey.instance)
        }
    }

    /// Gets a value that indicates whether the caller must call a `schedule` method.
    public static fileprivate(set) var isScheduleRequired: Bool {
       。。。
    }

    
    public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        。。。
    }
}

源码很简单,没什么好多说的。ConcurrentDispatchQueueScheduler ,SerialDispatchQueueScheduler是类似的,主要思路就是:初始化时使用 self.configuration 保存了传入的 DispatchQueue 对象。

public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        return self.scheduleInternal(state, action: action)
    }
--------------------------------------------------
  func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        return self.configuration.schedule(state, action: action)
    }
-------------------------------------------------
struct DispatchQueueConfiguration {
    let queue: DispatchQueue
    let leeway: DispatchTimeInterval
}
-------------------------------------------------
extension DispatchQueueConfiguration {
    func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        let cancel = SingleAssignmentDisposable()

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

        return cancel
    }
    …
}

而具体Scheduler如何调度执行的。我们上个例子说明一下:

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)

主要分析下 .observeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "observeOnSerial"))到底底层是如何执行的。

public func observeOn(_ scheduler: ImmediateSchedulerType)
        -> Observable {
            if let scheduler = scheduler as? SerialDispatchQueueScheduler {
                return ObserveOnSerialDispatchQueue(source: self.asObservable(), scheduler: scheduler)
            }
            else {
                return ObserveOn(source: self.asObservable(), scheduler: scheduler)
            }
    }

下面创建了一个ObserveOnSerialDispatchQueue序列:

final private class ObserveOnSerialDispatchQueue: Producer {
    let scheduler: SerialDispatchQueueScheduler
    let source: Observable

    init(source: Observable, scheduler: SerialDispatchQueueScheduler) {
        self.scheduler = scheduler
        self.source = source

        #if TRACE_RESOURCES
            _ = Resources.incrementTotal()
            _ = increment(_numberOfSerialDispatchQueueObservables)
        #endif
    }

    override func run(_ 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)
    }

    #if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
        _ = decrement(_numberOfSerialDispatchQueueObservables)
    }
    #endif
}

ObserveOnSerialDispatchQueue序列,继承至produce,保存了
self.scheduler = scheduler ——>队列,就是我们传进来的串行队列
self.source = source ——>源序列,of创建的ob
返回了一个序列 ObserveOnSerialDispatchQueue
这个序列去 subscribe,必然会进入到produce的subscribe方法:

class Producer : Observable {
    override init() {
        super.init()
    }

override func subscribe(_ 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
        }
    }
}

第一次没有调度环境,所以走下面CurrentThreadScheduler.instance.schedule(()){闭包}

public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        if CurrentThreadScheduler.isScheduleRequired {
            //标记一下 false 了
            CurrentThreadScheduler.isScheduleRequired = false
            //action(state)闭包调用
            let disposable = action(state)

           。。。
}

通过let disposable = action(state),调用闭包

{ _ in
            let disposer = SinkDisposer()
            let sinkAndSubscription = self.run(observer, cancel: disposer)
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }

run方法,produce的run方法,在子类中实现了,走子类ObserveOnSerialDispatchQueue 的run方法

final private class ObserveOnSerialDispatchQueue: Producer {
   。。。

    override func run(_ 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)
    }
。。。
}

后面的逻辑类似map,创建序列用的是of方法,所以是一个ObserveableSequence序列类型(打印一下就知道了),所以run方法走下面的ObservableSequenceSink里面的run:


final private class ObservableSequenceSink: Sink where Sequence.Element == Observer.Element {
    typealias Parent = ObservableSequence

    private let _parent: Parent

    init(parent: Parent, observer: Observer, cancel: Cancelable) {
        self._parent = parent
        super.init(observer: observer, cancel: cancel)
    }

    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._scheduler.scheduleRecursive中,self._parent== ObservableSequence,._scheduler是序列of时创建的:

 public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable {
        return ObservableSequence(elements: elements, scheduler: scheduler)
    }

scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance这个是默认值,scheduleRecursive一个调度递归:

public func scheduleRecursive(_ 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)
    }


----------------recursiveScheduler.schedule(state)----------------

 func schedule(_ state: State) {
        var scheduleState: ScheduleState = .initial

        let d = self._scheduler.schedule(state) { state -> Disposable in
            // best effort
            if self._group.isDisposed {
                return Disposables.create()
            }
            
            let action = self._lock.calculateLocked { () -> Action? in
                switch scheduleState {
                case let .added(removeKey):
                    self._group.remove(for: removeKey)
                case .initial:
                    break
                case .done:
                    break
                }

                scheduleState = .done

                return self._action
            }
            
            if let action = action {
                action(state, self.schedule)
            }
            
            return Disposables.create()
        }
        ...
}

通过if let action = action {action(state, self.schedule) }调用闭包,发送响应后进入到中间层ObserveOnSerialDispatchQueue的那个ObserveOnSerialDispatchQueueSink内的onCore方法:

  override func onCore(_ event: Event) {
        _ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!)
    }

----------------------------------------------------
  public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        return self.scheduleInternal(state, action: action)
    }
----------------------------------------------------
    func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        return self.configuration.schedule(state, action: action)
    }

----------------------------------------------------
extension DispatchQueueConfiguration {
    func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        let cancel = SingleAssignmentDisposable()

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

        return cancel
    }
    ….
}

解析到这里,其实.observeOn(SerialDispatchQueueScheduler.init(internalSerialQueueName: "observeOnSerial"))就已经解析完毕了,其实还是那套核心逻辑,只不过多了个中间层,多了个config的配置而已。

你可能感兴趣的:(08RxSwift的调度者Scheduler)