RxSwift-TakeUntil源碼分析

上文RxSwift-deallocating,deallocated源碼解析,我們提到deallocating序列和takeUntil序列經常結合起來使用,本文將分析takeUntil,探索一下takeUntil內部是如何接收deallocating發送的響應非常有必要。

takeUntil源碼解析

  public func takeUntil<Source: ObservableType>(_ other: Source)
        -> Observable<Element> {
        return TakeUntil(source: self.asObservable(), other: other.asObservable())
    }

返回的是一個TakeUntil序列,TakeUntil對象依然繼承自我們熟悉的Producer

final private class TakeUntil<Element, Other>: Producer<Element> {
    
    fileprivate let _source: Observable<Element>
    fileprivate let _other: Observable<Other>
    
    init(source: Observable<Element>, other: Observable<Other>) {
        self._source = source
        self._other = other
    }
    
    override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        let sink = TakeUntilSink(parent: self, observer: observer, cancel: cancel)
        let subscription = sink.run()
        return (sink: sink, subscription: subscription)
    }
}

TakeUntil序列保存了原始序列_source(上文的例子中,_source保存的是vc.publicOB序列)以及序列_other(上文的例子中,_other保存的就是vc.rx.deallocating序列)
外界的subscribe的是TakeUntil序列。TakeUntil序列被訂閱時,會執行TakeUntil.run,TakeUntil.run調用TakeUntilSink.run

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

TakeUntilSink保存TakeUntil_parent屬性.

 func run() -> Disposable {
        let otherObserver = TakeUntilSinkOther(parent: self)
        let otherSubscription = self._parent._other.subscribe(otherObserver)
        otherObserver._subscription.setDisposable(otherSubscription)
        let sourceSubscription = self._parent._source.subscribe(self)
        
        return Disposables.create(sourceSubscription, otherObserver._subscription)
    }

TakeUntilSink.run中,
1.創建觀察者TakeUntilSinkOther, TakeUntilSinkOther_parent保存TakeUntilSink
2.self._parent._other.subscribe(otherObserver)訂閱序列,這個序列就是上文的例子的vc.rx.deallocating序列。

RxSwift-deallocating,deallocated源碼解析中,我們提到當對象在dealloc時,會向DeallocatingProxy中存儲ReplaySubject序列(就是vc.rx.deallocating序列)發送響應,會來到這里的觀察者TakeUntilSinkOther.on(.next())

func on(_ event: Event<Element>) {
        self.synchronizedOn(event)
    }

    func _synchronized_on(_ event: Event<Element>) {
        switch event {
        case .next:
            self._parent.forwardOn(.completed)
            self._parent.dispose()
        case .error(let e):
            self._parent.forwardOn(.error(e))
            self._parent.dispose()
        case .completed:
            self._subscription.dispose()
        }
    }

TakeUntilSinkOther.on(.next())----->Sink.forwardOn(.completed)----->TakeUntilSink.observer.(.completed).
最終會給TakeUntil序列的observer發送.completed信號,序列完成并銷毀。

總結

1.takeUntil是一個中間層,在takeUntil被訂閱的流程中,中間層takeUntil會訂閱rx.deallocating()序列.
2.當對象被銷毀,對rx.deallocating()發送響應時,會調用到觀察者的TakeUntilSinkOther.on(.next()),最終會給TakeUntil序列的observer發送.completed信號,序列完成并銷毀。

TakeUntil.png

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容