RxSwift之深入解析dispose源码的实现原理
生活随笔
收集整理的這篇文章主要介紹了
RxSwift之深入解析dispose源码的实现原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、前言
- 任何對象都有生命周期,有創建就要銷毀。OC 中有 init 和 dealloc,swift 有 init 和 deinit,RxSwift 也不例外,有 create 和 dispose。
- RxSwift 有兩種清除方式:
-
- 訂閱產生的可清除資源(Disposable)對象,調用 dispose 方法清除;
-
- 通過清除包 DisposeBag 清除,在作用域結束后被釋放,也可以在需要的時候置空釋放。
- 無論哪種方式,最終都是調用 dispose() 方法來釋放。
- 例如,現有如下代碼,基礎序列的創建和訂閱:
- 運行結果如下所示:
- 可以發現在調用 dispose.dispose() 后,先執行的創建序列的回調閉包 Disposables.create { print(“銷毀釋放”)},再執行 {print(“銷毀回調”)},那么:
-
- 為什么調用 dispose() 方法能夠執行創建序列時的閉包呢?
-
- 為什么是先執行創建序列的閉包,再執行后面的銷毀回調閉包呢?
-
- dispose() 方法到底是如何實現銷毀序列的呢?銷毀的是什么?
二、銷毀者創建
- 點進 Disposables.create,可以看到返回了一個匿名銷毀者 AnonymousDisposable:
- 繼續,可以看到在 AnonymousDisposable 里,對象初始化,將外界傳入的閉包保存在_disposeAction 里:
- 那么在什么時候調用的呢?繼續,可以看到下面的 dispose() 方法:
- 這里有個重要的方法,fetchOr(self._isDisposed, 1),它是一個單項標記手段,this.value 初值是 0,所以返回的 oldValue 也是 0。
-
- 傳的 mask 是 1,this.value |= mask 按位或運算,this.value 值變為 1;
-
- 只有第一次調用 fetchOr,,返回的是 0 , 第二次以后,再調用 fetchOr,返回的都是1。
- fetchOr 調用一次后,_isDisposed 就會 變為 1,其實就是屬性標記,保證 dispose() 只執行一次。它這個標記方法中,沒有直接操作業務屬性,所以不會產生依賴,并且使用的是位運算,更加快速。
- dispose() 中,將 _disposeAction 保存到 action,清除 _disposeAction, 執行 action()。銷毀的代碼只執行一次,所以當前 _disposeAction 置為 nil 后,再執行尾隨必包 action:
三、銷毀 dispose() 方法調用
- 上面的流程,是在 subscriberHandle 回調閉包中,在 subscriberHandle 之還有一個重要的訂閱流程 subscribe:
- 在 subsricbe 進入訂閱方法內容,可以看到:在這里保存外界這個銷毀提示的閉包:
- 注意到創建 observer 里的 event,可以看到在 .error 和 .completed 里,都調用 dispose 方法,也就是上面 AnonymousDisposable 里的 dispose 方法,在完成或者報錯后,要銷毀這個訂閱關系:
- 那么,.next 事件是如何調用 dispose 的呢?我們注意到這里創建了一個銷毀者 Disposables,繼續進入:
- 創建一個 BinaryDisposable 二元銷毀者,把剛剛的兩個要銷毀的 disposable 都傳進去,返回Disposables可以讓外界隨時隨地的調用 dispose():
- 點進 BinaryDisposable,可以看到把傳遞進來的 disposable1 和 disposable2 都保存起來:
- 二元銷毀者保存 2 個銷毀者對象 _disposable1 和 _disposable2,dispose() 使用 fetchOr 保證銷毀代碼執行一次,分別調用 2 個銷毀者的 dispose() 方法,并設置為 nil。self.asObservable().subscribe(observer) 方法的調用,我們知道訂閱流程會來到 Producer 的 subscribe(observer)。這里也看到有一個 dispose() 方法:
- 那么,self.asObservable().subscribe(observer) 里創建的關鍵銷毀者到底是什么呢?
- 直接找 Producer 里的 subscribe 方法(為什么直接找 Producer 呢?在 RxSwift 核心邏輯的時候,了解 Producer 里的 subscribe 是會先執行的,具體請參考:RxSwift之深入解析核心邏輯Observable的底層原理),可以看到 SinkDisposer(),如下所示:
- 首先看看 self.run 返回的是什么?可以發現,返回的是 AnonymousObservableSink 和 subscription 一個元組類型,subscription 是一個 AnonymousDisposable:
- 可能會不理解為什么是 AnonymousDisposable?因為 sink.run 就是調用的這里保存的 _subscribeHandler,而這個 _subscribeHandler 是由外界傳遞過來的閉包,就是 create 后面跟隨的閉包:
- 繼續,那么 disposer.setSinkAndSubscription 干了什么事情呢?
- 這里把 sink 和 subscription 都保存起來了,還可以看到有一個 previousState 的狀態,如果狀態滿足的話,就會調用銷毀方法,把這兩個都銷毀。其實是可以理解為,就是在加入的對象其實需要銷毀的,不應該保留的,那么沒必要給它繼續保留生命周期。
- 普通的銷毀者是 AnonymousDisposable,而這里使用的是 SinkDisposer:
-
- 初始化 SinkDisposer 類型的 disposer;
-
- sinkAndSubscription 是子類返回的元組 (sink: sink, subscription: subscription),
sink 保存觀察者 observer,銷毀者 disposer,subscription 保存的是外界返回的銷毀者;
- sinkAndSubscription 是子類返回的元組 (sink: sink, subscription: subscription),
-
- disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription),disposer 保存 _sink 和 subscription previousState 狀態判斷對象是否已經銷毀,如果已銷毀則調用 sink 和 _subscription 的 dispose() 并設置為 nil;
-
- SinkDisposer 的 func dispose() 通過 previousState 狀態保證只銷毀一次,
sink 和 _subscription 分別調用 dispose() 并設置為 nil。
- SinkDisposer 的 func dispose() 通過 previousState 狀態保證只銷毀一次,
- dispose() 方法在什么時候執行?
-
- 完成和錯誤信號的響應式必然會直接開啟銷毀;
-
- 手動調用 dispose.dispose();
-
- 系統幫助銷毀。
四、銷毀的本質
- 通過分析,我們知道 RxSwift 的銷毀者實際上銷毀的是響應式關系。RxSwift 通過序列和觀察者來建立響應關系,如果斷開,響應關系就已達到銷毀的目標。
- 關于對象的回收,外界觀察者和序列會隨著它們的作用域空間而釋放,內部創建的臨時序列和觀察者都會隨著對外的觀察者和序列的生命周期而銷毀釋放。
五、總結
- Disposables.create(self.asObservable().subscribe(observer),disposable) 調用訂閱時創建的 Disposables的dispose(),然后對二元銷毀者分別調用 dispose() 并設置為 nil;
- disposable 保存的是訂閱時傳入的閉包,disposable.dispose() 銷毀 RxSwift 與外界的關聯。self.asObservable().subscribe(observer) 是 SinkDisposer,因此調用的是 SinkDisposer.dispose();
- SinkDisposer.dispose() 對保存的 2 個屬性分別調用 dispose() 并設置為nil,subscription 保存的是外界創建序列時的閉包,因此 subscription.dispose() 也是切斷RxSwift 與外界的關聯,_sink.dispose() 調用保存的屬性_cancel的dispose()。
- RxSwift 為了統一性,會對保存的屬性都調用一次 dispose(),如果有相互包含的屬性,會有相互調用 dispose() 的情況。比如,SinkDisposer.dispose() 會調用 sink.dispose(),而執行 sink.dispose() 又將會執行 SinkDisposer.dispose()。
總結
以上是生活随笔為你收集整理的RxSwift之深入解析dispose源码的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Swift之从SIL深入分析函数的派发机
- 下一篇: RxSwift之深入解析特殊序列deal