日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RxSwift之深入解析dispose源码的实现原理

發布時間:2024/5/21 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RxSwift之深入解析dispose源码的实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

  • 任何對象都有生命周期,有創建就要銷毀。OC 中有 init 和 dealloc,swift 有 init 和 deinit,RxSwift 也不例外,有 create 和 dispose。
  • RxSwift 有兩種清除方式:
    • 訂閱產生的可清除資源(Disposable)對象,調用 dispose 方法清除;
    • 通過清除包 DisposeBag 清除,在作用域結束后被釋放,也可以在需要的時候置空釋放。
  • 無論哪種方式,最終都是調用 dispose() 方法來釋放。
  • 例如,現有如下代碼,基礎序列的創建和訂閱:
// 創建序列let ob = Observable<Any>.create { (observer) -> Disposable inobserver.onNext("ABC")return Disposables.create { print("銷毀釋放")} // dispose.dispose()}// 序列訂閱let dispose = ob.subscribe(onNext: { (anything) inprint("訂閱到:\(anything)")}, onError: { (error) inprint("訂閱到:\(error)")}, onCompleted: {print("完成")}) {print("銷毀回調")}print("執行完畢")// 銷毀序列dispose.dispose()
  • 運行結果如下所示:
訂閱到:ABC執行完畢銷毀釋放銷毀回調
  • 可以發現在調用 dispose.dispose() 后,先執行的創建序列的回調閉包 Disposables.create { print(“銷毀釋放”)},再執行 {print(“銷毀回調”)},那么:
    • 為什么調用 dispose() 方法能夠執行創建序列時的閉包呢?
    • 為什么是先執行創建序列的閉包,再執行后面的銷毀回調閉包呢?
    • dispose() 方法到底是如何實現銷毀序列的呢?銷毀的是什么?

二、銷毀者創建

  • 點進 Disposables.create,可以看到返回了一個匿名銷毀者 AnonymousDisposable:
public static func create(with dispose: @escaping () -> Void) -> Cancelable {return AnonymousDisposable(disposeAction: dispose)} fileprivate final class AnonymousDisposable : DisposeBase, Cancelable {public typealias DisposeAction = () -> Void/// Constructs a new disposable with the given action used for disposal.////// - parameter disposeAction: Disposal action which will be run upon calling `dispose`.fileprivate init(_ disposeAction: @escaping DisposeAction) {self._disposeAction = disposeActionsuper.init()}}
  • 繼續,可以看到在 AnonymousDisposable 里,對象初始化,將外界傳入的閉包保存在_disposeAction 里:
fileprivate init(_ disposeAction: @escaping DisposeAction) {self._disposeAction = disposeActionsuper.init()}
  • 那么在什么時候調用的呢?繼續,可以看到下面的 dispose() 方法:
// 核心邏輯fileprivate func dispose() {if fetchOr(self._isDisposed, 1) == 0 {if let action = self._disposeAction {self._disposeAction = nilaction()}}}
  • 這里有個重要的方法,fetchOr(self._isDisposed, 1),它是一個單項標記手段,this.value 初值是 0,所以返回的 oldValue 也是 0。
    • 傳的 mask 是 1,this.value |= mask 按位或運算,this.value 值變為 1;
    • 只有第一次調用 fetchOr,,返回的是 0 , 第二次以后,再調用 fetchOr,返回的都是1。
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {this.lock()let oldValue = this.value // 0 1this.value |= mask // 1 1this.unlock()return oldValue // 0 1 1 1 1 1 1 1}
  • fetchOr 調用一次后,_isDisposed 就會 變為 1,其實就是屬性標記,保證 dispose() 只執行一次。它這個標記方法中,沒有直接操作業務屬性,所以不會產生依賴,并且使用的是位運算,更加快速。
  • dispose() 中,將 _disposeAction 保存到 action,清除 _disposeAction, 執行 action()。銷毀的代碼只執行一次,所以當前 _disposeAction 置為 nil 后,再執行尾隨必包 action:
// 核心邏輯fileprivate func dispose() {if fetchOr(self._isDisposed, 1) == 0 {if let action = self._disposeAction {self._disposeAction = nilaction()}}}

三、銷毀 dispose() 方法調用

  • 上面的流程,是在 subscriberHandle 回調閉包中,在 subscriberHandle 之還有一個重要的訂閱流程 subscribe:
public func subscribe(onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)-> Disposable {let disposable: Disposableif let disposed = onDisposed {disposable = Disposables.create(with: disposed)}else {disposable = Disposables.create()}}
  • 在 subsricbe 進入訂閱方法內容,可以看到:在這里保存外界這個銷毀提示的閉包:
if let disposed = onDisposed {disposable = Disposables.create(with: disposed) } else {disposable = Disposables.create()}
  • 注意到創建 observer 里的 event,可以看到在 .error 和 .completed 里,都調用 dispose 方法,也就是上面 AnonymousDisposable 里的 dispose 方法,在完成或者報錯后,要銷毀這個訂閱關系:
switch event {case .next(let value):onNext?(value)case .error(let error):if let onError = onError {onError(error)}disposable.dispose()case .completed:onCompleted?()disposable.dispose()}}
  • 那么,.next 事件是如何調用 dispose 的呢?我們注意到這里創建了一個銷毀者 Disposables,繼續進入:
return Disposables.create(self.asObservable().subscribe(observer),disposable)
  • 創建一個 BinaryDisposable 二元銷毀者,把剛剛的兩個要銷毀的 disposable 都傳進去,返回Disposables可以讓外界隨時隨地的調用 dispose():
// Creates a disposable with the given disposables.public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {return BinaryDisposable(disposable1, disposable2)}
  • 點進 BinaryDisposable,可以看到把傳遞進來的 disposable1 和 disposable2 都保存起來:
private final class BinaryDisposable : DisposeBase, Cancelable {private let _isDisposed = AtomicInt(0)// stateprivate var _disposable1: Disposable?private var _disposable2: Disposable?/// - returns: Was resource disposed.var isDisposed: Bool {return isFlagSet(self._isDisposed, 1)}/// Constructs new binary disposable from two disposables.////// - parameter disposable1: First disposable/// - parameter disposable2: Second disposableinit(_ disposable1: Disposable, _ disposable2: Disposable) {self._disposable1 = disposable1self._disposable2 = disposable2super.init()}func dispose() {if fetchOr(self._isDisposed, 1) == 0 {self._disposable1?.dispose()self._disposable2?.dispose()self._disposable1 = nilself._disposable2 = nil}}}
  • 二元銷毀者保存 2 個銷毀者對象 _disposable1 和 _disposable2,dispose() 使用 fetchOr 保證銷毀代碼執行一次,分別調用 2 個銷毀者的 dispose() 方法,并設置為 nil。self.asObservable().subscribe(observer) 方法的調用,我們知道訂閱流程會來到 Producer 的 subscribe(observer)。這里也看到有一個 dispose() 方法:
func dispose() {if fetchOr(self._isDisposed, 1) == 0 {self._disposable1?.dispose()self._disposable2?.dispose()self._disposable1 = nilself._disposable2 = nil}}
  • 那么,self.asObservable().subscribe(observer) 里創建的關鍵銷毀者到底是什么呢?
return Disposables.create(self.asObservable().subscribe(observer),disposable)
  • 直接找 Producer 里的 subscribe 方法(為什么直接找 Producer 呢?在 RxSwift 核心邏輯的時候,了解 Producer 里的 subscribe 是會先執行的,具體請參考:RxSwift之深入解析核心邏輯Observable的底層原理),可以看到 SinkDisposer(),如下所示:
let disposer = SinkDisposer()let sinkAndSubscription = self.run(observer, cancel: disposer) disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
  • 首先看看 self.run 返回的是什么?可以發現,返回的是 AnonymousObservableSink 和 subscription 一個元組類型,subscription 是一個 AnonymousDisposable:
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {let sink = AnonymousObservableSink(observer: observer, cancel: cancel)let subscription = sink.run(self)return (sink: sink, subscription: subscription)}
  • 可能會不理解為什么是 AnonymousDisposable?因為 sink.run 就是調用的這里保存的 _subscribeHandler,而這個 _subscribeHandler 是由外界傳遞過來的閉包,就是 create 后面跟隨的閉包:
// 創建序列let ob = Observable<Any>.create { (observer) -> Disposable inobserver.onNext("1111")return Disposables.create { print("銷毀釋放了")} // dispose.dispose()}
  • 繼續,那么 disposer.setSinkAndSubscription 干了什么事情呢?
let disposer = SinkDisposer()let sinkAndSubscription = self.run(observer, cancel: disposer) disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
  • 這里把 sink 和 subscription 都保存起來了,還可以看到有一個 previousState 的狀態,如果狀態滿足的話,就會調用銷毀方法,把這兩個都銷毀。其實是可以理解為,就是在加入的對象其實需要銷毀的,不應該保留的,那么沒必要給它繼續保留生命周期。
func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {self._sink = sinkself._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 = nilself._subscription = nil}}
  • 普通的銷毀者是 AnonymousDisposable,而這里使用的是 SinkDisposer:
    • 初始化 SinkDisposer 類型的 disposer;
    • sinkAndSubscription 是子類返回的元組 (sink: sink, subscription: subscription),
      sink 保存觀察者 observer,銷毀者 disposer,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。
  • dispose() 方法在什么時候執行?
    • 完成和錯誤信號的響應式必然會直接開啟銷毀;
    • 手動調用 dispose.dispose();
    • 系統幫助銷毀。
private func dispose() {let oldDisposables = self._dispose()for disposable in oldDisposables {disposable.dispose()}}private func _dispose() -> [Disposable] {self._lock.lock(); defer { self._lock.unlock() }let disposables = self._disposablesself._disposables.removeAll(keepingCapacity: false)self._isDisposed = truereturn disposables}deinit {self.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源码的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。