對Observable.of方法的探究

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

    Observable.of方法接受一個不定參數,其返回一個ObservableSequence類型的Observable,該Observable默認是持有一個CurrentThreadScheduler,該類是一個當前線程任務調度器,調度器內部有一個隊列類型,用來存放已提交的還沒執行的任務,只要調度器執行完成當前任務,他將執行其隊列內部的任務。

    該方法整體的邏輯是,創建一個匿名的觀察者AnonymousObserver,其持有相應事件的代碼

                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {
                case .next(let value):
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }

然後調用Observable的subscribe方法,將自己(Observable與Observer)關聯,此處的Observable是ObservableSequence類型,ObservableSequence是Producer的子類,ObservablerSequence的subscribe方法是直接繼承Producer的。我們看一下Producer的Subscribe代碼:

    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == 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 {
            //開啓一個當前線程任務調度器調度了一個任務,該任務啓動了observable,sink,observer三個對象的關聯
            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//這個disposer
            }
        }
    }

其實subscribe方法做的事情就是調用自身的run方法實現observer與observable的綁定,至於if else,CurrentThreadScheduler是多線程相關的代碼,不是我們關心的重點。接下來我們看一下ObservableSequence的run方法

    override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E {
        let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel)
        let subscription = sink.run()
        return (sink: sink, subscription: subscription)
    }

這裏我們看到,代碼裏用到了ObservableSequenceSink的類型,其持有了ObserverSequence與觀察者還有上面代碼傳過來的SinkDisposer。ObservableSequenceSink是專門爲ObserverSequence而服務的Sink,Sink我們可以理解爲管道,將Observable的信號傳遞給Observer的橋樑。接下來我們看一下ObservableSequenceSink的run方法是如何執行的。

    func run() -> Disposable {
        //啓動管道,讓調度器開啓一個遞歸調度代碼塊,這個代碼塊是發送信號的核心(爲什麼要遞歸地執行代碼?)
        return self._parent._scheduler.scheduleRecursive(self._parent._elements.makeIterator()) { iterator, recurse in
            var mutableIterator = iterator
            print("state=\(iterator)")
            if let next = mutableIterator.next() {
                print(next)
                self.forwardOn(.next(next))//發送了一次信號
                recurse(mutableIterator)
            }
            else {
                self.forwardOn(.completed)
                self.dispose()
            }
        }
    }

這裏run方法做的事情就是在CurrentThreadScheduler裏遞歸地投遞任務,如何實現遞歸地投遞?我們看一下scheduleRecursive的代碼:

    public func scheduleRecursive<State>(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> Void) -> Void) -> Disposable {
        let recursiveScheduler = RecursiveImmediateScheduler(action: action, scheduler: self)//此處action就是發送信號的action
        
        recursiveScheduler.schedule(state)//提交了一個任務到CurrentScheduler
        
        return Disposables.create(with: recursiveScheduler.dispose)
    }

這裏是通過RecursiveImmediateScheduler來實現遞歸的投遞任務,從該類的名字我們很容易知道該類的作用:遞歸地投遞立即執行的任務,他的schedule方法是投遞任務的關鍵,我們來看一下schedule方法的實現:

    func schedule(_ state: State) {
        var scheduleState: ScheduleState = .initial
        //這裏的又啓動了一個任務,但是這個任務並不能馬上執行,所以該任務被封裝成ScheduleItem放入Scheduler的執行隊列裏了
        let d = self._scheduler.schedule(state) { state -> Disposable in
            // best effort
            if self._group.isDisposed {
                return Disposables.create()
            }
            //這裏拋開線程安全的代碼不看,做的事情其實就是1,將任務從自身group中移除,將並將當前任務狀態更改爲完成,並將自身所持有的action返回
            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
            }
            //執行action
            if let action = action {
                print("state=\(state)")
                action(state, self.schedule)//這裏的action其實是發送信號的action,這裏的self.schedule是遞歸的所在
            }
            
            return Disposables.create()
        }
        //這裏將任務的執行狀態設置爲加入隊列,任務狀態一共有三種,intial added done
        self._lock.performLocked {
            switch scheduleState {
            case .added:
                rxFatalError("Invalid state")
            case .initial:
                if let removeKey = self._group.insert(d) {
                    scheduleState = .added(removeKey)
                }
                else {
                    scheduleState = .done
                }
            case .done:
                break
            }
        }
    }

拋開線程安全的代碼不看,他就是在CurrentThreadScheduler裏投遞了一個任務,這個任務當前並沒有執行,而是等到當前任務執行完成後纔會執行,我們所執行的代碼就是當前執行的任務.

    public func schedule<StateType>(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable {
        if CurrentThreadScheduler.isScheduleRequired {
            CurrentThreadScheduler.isScheduleRequired = false

            let disposable = action(state)

            defer {
                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()//ScheduledItem要執行了
            }

            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的啓動任務方法,以上所講的代碼其實都是在let disposable=action(state)裏,都是在執行action().當RecursiveImmediateScheduler提交完遞歸任務後,代碼就會逐級返回,最終會回到CurrentThreadScheduler的schedule方法裏,繼續向下執行,(defer是一個語法糖,其保證defer的block會在函數將要返回之前執行,可以在defer block裏執行一些清理工作),接下來函數將保存好的ScheduleItem取出,執行,這裏的ScheduleItem所持有的block是RecursiveImmediateScheduler在他的schedule方法裏提交的,代碼如下:

        let d = self._scheduler.schedule(state) { state -> Disposable in
            // best effort
            if self._group.isDisposed {
                return Disposables.create()
            }
            //這裏拋開線程安全的代碼不看,做的事情其實就是1,將任務從自身group中移除,將並將當前任務狀態更改爲完成,並將自身所持有的action返回
            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
            }
            //執行action
            if let action = action {
                print("state=\(state)")
                action(state, self.schedule)//這裏的action其實是發送信號的action,這裏的self.schedule是遞歸的所在
            }
            
            return Disposables.create()
        }

其實就是執行RecursiveScheduler所持有的代碼:

            var mutableIterator = iterator
            print("state=\(iterator)")
            if let next = mutableIterator.next() {
                print(next)
                self.forwardOn(.next(next))//發送了一次信號
                recurse(mutableIterator)
            }
            else {
                self.forwardOn(.completed)
                self.dispose()
            }

該action的兩個參數,一個是由最開始調用Observable.of傳的sequence參數生成的迭代器,另一個參數是RecursiveScheduler的schedule函數。我們注意觀察這個action,這個action的大意是取出迭代器下一個元素,發送信號,然後再次執行RecursiveScheduler的schedule方法,其實就是再次提交一個任務到CurrentThreadScheduler,提交這個任務時,迭代器還是最開始的那個迭代器,只是他的next已經指向了下一個元素,也就能發送下一個信號了,隨着迭代器持續的next(),最後迭代器的next方法將返回nil,那麼action將發送完成信號,然後開始清理工作。至此,Observable.of().suscribe方法已經完成了信號發送,響應。

我們再看一下forwardOn代碼:

    final func forwardOn(_ event: Event<O.E>) {
        #if DEBUG
            self._synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { self._synchronizationTracker.unregister() }
        #endif
        if isFlagSet(&self._disposed, 1) {
            return
        }
        self._observer.on(event)
    }

這段代碼就是調用了其持有的觀察者的on block,也就是匿名觀察者持有的信號響應block,這個block判斷信號,如果是.next的,就會調用最開始你寫的響應方法,也就完成了信號的相應。

RxSwift是一個優秀的框架,本人水平有限,如有錯誤,請批評指正,如果轉載,請附上原鏈接

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章