RxSwift-dispose源碼解析

任何對(duì)象都有生命周期,有創(chuàng)建就要銷毀。 OC中有initdeallocswiftinitdeinit,RxSwift也不例外,RxSwiftcreatedispose。下面就看看dispose是如何管理序列銷毀的。

一篇沒有配圖的文章是沒有靈魂的??

disposable.png

通過前面了解了RxSwift的兩種清除方式:

  • 訂閱產(chǎn)生的可清除資源(Disposable)對(duì)象,調(diào)用dispose方法清除
  • 通過清除包DisposeBag清除,在作用域結(jié)束后被釋放,也可以在需要的時(shí)候置空釋放

無論哪種方式,最終都是調(diào)用dispose()方法來釋放。

下面看一段序列由創(chuàng)建到銷毀:

//創(chuàng)建一個(gè)序列
let ob = Observable<Any>.create { (observer) -> Disposable in
        observer.onNext("msg")
        return Disposables.create{
            print("被銷毀")
        }
    }
//訂閱序列
let dis = ob.subscribe(onNext: { (val) in
        print(val)
    }){
        print("銷毀了")
}
//銷毀訂閱
dis.dispose()

此處代碼,我們調(diào)用了dispose方法來銷毀對(duì)象,銷毀者dis其實(shí)和創(chuàng)建序列時(shí)返回的Disposables對(duì)象并不是一個(gè)對(duì)象。

disposable對(duì)象創(chuàng)建代碼:

extension Disposables {
    public static func create(with dispose: @escaping () -> Void) -> Cancelable {
        return AnonymousDisposable(disposeAction: dispose)
    }
}
  • 實(shí)質(zhì)上創(chuàng)建了一個(gè)AnonymousDisposable類型的銷毀者對(duì)象
  • 傳入了業(yè)務(wù)層的監(jiān)聽閉包,銷毀對(duì)象時(shí)用來通知
fileprivate final class AnonymousDisposable : DisposeBase, Cancelable {
    public typealias DisposeAction = () -> Void

    private var _isDisposed = AtomicInt(0)
    private var _disposeAction: DisposeAction?

    public var isDisposed: Bool {
        return isFlagSet(&self._isDisposed, 1)
    }

    fileprivate init(disposeAction: @escaping DisposeAction) {
        self._disposeAction = disposeAction
        super.init()
    }
    fileprivate func dispose() {
        if fetchOr(&self._isDisposed, 1) == 0 {
            if let action = self._disposeAction {
                self._disposeAction = nil
                action()
            }
        }
    }
}
  • 初始化保存業(yè)務(wù)層,創(chuàng)建銷毀者對(duì)象實(shí)現(xiàn)的閉包
  • dispose()為銷毀方法,該方法調(diào)用后就銷毀了傳入的閉包對(duì)象
  • 判斷實(shí)列是否被釋放,未釋放就執(zhí)行執(zhí)行對(duì)保存閉包的置空操作
  • action()通知業(yè)務(wù)層釋放監(jiān)聽閉包,通知完成出{}作用域action即被釋放

再看看訂閱者中的銷毀者的創(chuàng)建(代碼標(biāo)記為1??):

public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
    -> Disposable {
        let disposable: Disposable
        
        if let disposed = onDisposed {
            disposable = Disposables.create(with: disposed)
        }
        else {
            disposable = Disposables.create()
        }
        
        #if DEBUG
            let synchronizationTracker = SynchronizationTracker()
        #endif
        
        let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
        
        let observer = AnonymousObserver<E> { event in
            
            #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()
            }
        }
        return Disposables.create(
            self.asObservable().subscribe(observer),
            disposable
        )
}
  • onDisposed外部實(shí)現(xiàn)的銷毀者閉包,實(shí)現(xiàn)即傳入閉包,否則直接調(diào)用create()創(chuàng)建,目的是對(duì)外發(fā)出銷毀通知
  • 最后又創(chuàng)建了一個(gè)銷毀者對(duì)象并返回,可在業(yè)務(wù)層做銷毀操作,該銷毀對(duì)象保存了self.asObservable().subscribe(observer)返回的銷毀者,和當(dāng)前方法中創(chuàng)建的銷毀者。what???搞毛啊,這么多銷毀者,怕我還不夠迷糊嗎??!

銷毀者Disposables有多種擴(kuò)展,為滿足不同需求:

  1. 需要在序列創(chuàng)建處觀察銷毀情況;
  2. 前面幾篇文章有講到,在調(diào)用onError,onCompleted方法會(huì)銷毀我們的序列,在業(yè)務(wù)層省去了開發(fā)人員去銷毀序列的步驟;
  3. 根據(jù)不同業(yè)務(wù)需求,需要滿足開發(fā)人員銷毀序列的功能。

因此以上出現(xiàn)了這么多的銷毀者,最終銷毀者還是被同類銷毀者(不同擴(kuò)展)所管理??匆幌伦詈笠粋€(gè)銷毀者內(nèi)部做了哪些事情:

extension Disposables {
    public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
        return BinaryDisposable(disposable1, disposable2)
    }
}
  • 收集前面所創(chuàng)建的銷毀者到BinaryDisposable對(duì)象中
private final class BinaryDisposable : DisposeBase, Cancelable {

    private var _isDisposed = AtomicInt(0)

    // state
    private var _disposable1: Disposable?
    private var _disposable2: Disposable?

    /// - returns: Was resource disposed.
    var isDisposed: Bool {
        return isFlagSet(&self._isDisposed, 1)
    }

    init(_ disposable1: Disposable, _ disposable2: Disposable) {
        self._disposable1 = disposable1
        self._disposable2 = disposable2
        super.init()
    }

    func dispose() {
        if fetchOr(&self._isDisposed, 1) == 0 {
            self._disposable1?.dispose()
            self._disposable2?.dispose()
            self._disposable1 = nil
            self._disposable2 = nil
        }
    }
}
  • 繼承了Disposable協(xié)議,并實(shí)現(xiàn)了協(xié)議方法dispose()

該類中實(shí)現(xiàn)了dispose()方法,該方法即是外部訂閱后調(diào)用的dispose()方法,銷毀所有創(chuàng)建序列時(shí)產(chǎn)生的銷毀者,銷毀之前各自掉用各自的dispose方法,來銷毀外界保留的閉包對(duì)象,并向業(yè)務(wù)層發(fā)送銷毀通知。

下面看一下代碼1??處self.asObservable().subscribe(observer)的銷毀者是如何產(chǎn)生的:

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

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

又是我們熟悉的Producer,熟悉的sink,在該處創(chuàng)建了一個(gè)SinkDisposer對(duì)象,應(yīng)該又是一個(gè)銷毀者:

fileprivate final class SinkDisposer: Cancelable {}
  • 繼承自Cancelable -> Disposable,并實(shí)現(xiàn)了dispose()方法
  • 銷毀者去向run -> AnonymousObservableSink -> Sink
  • Sink繼承自Disposable,實(shí)現(xiàn)了dispose()方法,內(nèi)部調(diào)用了外部傳入的銷毀者即SinkDisposer對(duì)象

setSinkAndSubscription該方法傳入了sink銷毀者和業(yè)務(wù)層創(chuàng)建序列時(shí)創(chuàng)建的銷毀者。代碼如下:

func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {
    self._sink = sink
    self._subscription = subscription

    let previousState = fetchOr(&self._state, DisposeState.sinkAndSubscriptionSet.rawValue)
    if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
        rxFatalError("Sink and subscription were already set")
    }

    if (previousState & DisposeState.disposed.rawValue) != 0 {
        sink.dispose()
        subscription.dispose()
        self._sink = nil
        self._subscription = nil
    }
}

保存了兩個(gè)銷毀者(Producer創(chuàng)建的銷毀者、業(yè)務(wù)層創(chuàng)建的銷毀者),這個(gè)地方其他的沒干就是想銷毀這兩個(gè)銷毀者:

sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil

置空前都調(diào)用了dispose(),這里面置空銷毀者,并向業(yè)務(wù)層發(fā)送了銷毀通知。

sink主要用來連接序列,觸發(fā)序列閉包,向觀察者發(fā)送消息。而sink清空所有內(nèi)部銷毀者后并置空,序列和訂閱者就失去聯(lián)系。

系統(tǒng)銷毀:

AnonymousObservableSink -> Sink -> dispose() -> SinkDisposer -> dispose()

外部銷毀:

BinaryDisposable -> AnonymousObservableSink -> Sink -> dispose() -> SinkDisposer -> dispose()

無論是系統(tǒng)銷毀,還是外部調(diào)用dispose銷毀最終所有產(chǎn)生的銷毀者都會(huì)被銷毀釋放。到此我們發(fā)現(xiàn)我們所銷毀的居然是外部對(duì)應(yīng)的監(jiān)聽閉包,內(nèi)部創(chuàng)建的Disposable的子類對(duì)象。

sink連接了序列和訂閱者,sink本身是Disposable對(duì)象,因此被銷毀后斷開了序列和訂閱者之間的聯(lián)系。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容