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