銷毀同樣是 RxSwift
中和序列,觀察,調(diào)度并列句伶,最重要的四個元素之一。
銷毀一般有兩種方法:
- 訂閱產(chǎn)生的可
Disposable
清除資源對象配猫,單獨調(diào)用dispose
方法進行銷毀 - 通過將產(chǎn)生的清除對象放到
DisposeBag
中,在作用域結(jié)束后被釋放杏死,也可以在需要的時候置空釋放泵肄。
初探
那么首先從基本序列創(chuàng)建和訂閱開始分析
- 例子:
let ob = Observable<Any>.create { (observer) -> Disposable in
observer.onNext("lb")
return Disposables.create {print("銷毀釋放了")}
}
let dispose = ob.subscribe(onNext: { (element) in
print("訂閱到了:\(element)")
}, onError: { (error) in
print("訂閱到了:\(error)")
}, onCompleted: {
print("完成")
}) {
print("銷毀回調(diào)")
}
print("執(zhí)行完畢")
dispose.dispose()
- 打印結(jié)果:
訂閱到了:lb
執(zhí)行完畢
銷毀釋放了
銷毀回調(diào)
- 分析:
點進去Disposables.create
點不進去的按老方法,直接搜索找淑翼,swift
會記錄 下一次就點的進了腐巢。
extension Disposables {
/// - parameter dispose: Disposal action which will be run upon calling `dispose`.
public static func create(with dispose: @escaping () -> Void) -> Cancelable {
return AnonymousDisposable(disposeAction: dispose)
}
}
再進入 AnonymousDisposable
fileprivate final class AnonymousDisposable : DisposeBase, Cancelable {
public typealias DisposeAction = () -> Void
private let _isDisposed = AtomicInt(0)
private var _disposeAction: DisposeAction?
fileprivate init(_ disposeAction: @escaping DisposeAction) {
self._disposeAction = disposeAction
super.init()
}
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()
}
}
}
}
跟訂閱方法類似,同樣是產(chǎn)生了一個匿名中間類 AnonymousDisposable
玄括。使用屬性保存了銷毀閉包參數(shù)冯丙。
這個類繼承與 DisposeBase
,遵循 Cancelable
的 protocol
惠豺,而且自己實現(xiàn)了 私有方法 dispose()
這個方法中 有一個 fetchOr
方法值得一提:
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()
let oldValue = this.value
this.value |= mask
this.unlock()
return oldValue
}
首先 其實現(xiàn)目的是為了保證滿足 if
條件里的代碼只執(zhí)行一次。采用與1進行位運算风宁,并且
private let _isDisposed = AtomicInt(0)
可以看出 self._isDisposed
的初始值是0洁墙,結(jié)合 fetchOr
具體方法實現(xiàn),達到只會執(zhí)行一次的效果戒财。
執(zhí)行 if
里的代碼
if let action = self._disposeAction {
self._disposeAction = nil
action()
}
先賦值到一個臨時變量 action
同時判斷 _disposeAction
為不為空热监,將自己的 _disposeAction
屬性置空,執(zhí)行銷毀回調(diào)饮寞。也就是我們寫的 print("銷毀釋放了")
那么這個
dispose()
方法干了啥我們搞清楚了孝扛,問題又來了 它是什么時候被調(diào)用的呢?
不著急幽崩,我們接著往下走苦始,來到我們寫的代碼中,走 ob.subscribe(onNext ...
慌申,這個方法很熟悉了陌选。直接進來
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()
}
let observer = AnonymousObserver<E> { event in
switch event {
case .next(let value):
onNext?(value)
case .error(let error):
if let onError = onError {
onError(error)
}
else { ... }
disposable.dispose()
case .completed:
onCompleted?()
disposable.dispose()
}
}
return Disposables.create(
self.asObservable().subscribe(observer),
disposable
)
}
這個方法中首先 Disposables.create
創(chuàng)建 Disposables
并保存了外界傳遞的銷毀回調(diào) 也就是我們寫的
print("銷毀回調(diào)")
接下來來到重點:
return Disposables.create(
self.asObservable().subscribe(observer),
disposable
)
這里可以看到, 它就是我們外界訂閱調(diào)用
subscribe
方法得到的返回,并且外界可以隨時調(diào)用這個返回的對象的.dispose()
方法進行銷毀.
直接點進去 .create方法
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
繼續(xù)進去該類 找 dispose
方法
func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
self._disposable1?.dispose()
self._disposable2?.dispose()
self._disposable1 = nil
self._disposable2 = nil
}
}
這個二元銷毀者的 dispose 方法也是常規(guī)操作,分別銷毀. 值得一提的是它是一個開放出來的方法,因此外界可以隨時調(diào)用該對象的銷毀方法.
- 接下來 回到
self.asObservable().subscribe(observer)
不做贅述. 直接找Producer
的subscribe
方法
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
run方法由子類自己實現(xiàn) ,從而來到 AnonymousObservable
的 run
方法中
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
眾所周知 sink.run
就是調(diào)用
這個 subscription
就是 AnonymousDisposable
。(原因是 sink.run
就是調(diào)用 AnonymousObservable
中保存的 _subscribeHandler
回調(diào) 也就是用戶創(chuàng)建 create
時初始化傳進來的). 而且我們 create
閉包中返回的是
AnonymousDisposable
也就是這句我們自己寫的代碼
let ob = Observable<Any>.create { (observer) -> Disposable in
observer.onNext("lb")
return Disposables.create {print("銷毀釋放了")}
}
然后就把 AnonymousObservableSink
和 AnonymousDisposable
打包進元組給返回了咨油。
再繼續(xù)看 SinkDisposer
的 setSinkAndSubscription
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
}
}
- 保存了
sink
和subscription
(就是外界創(chuàng)建序列的閉包的返回銷毀者) - 取了某一個狀態(tài):
previousState
,判斷狀態(tài)的條件您炉,然后執(zhí)行 這兩個保存屬性的銷毀和置空釋放銷毀
最后回來到外部我們自己敲的代碼中
來到
dispose.dispose()
也就是調(diào)用 BinaryDisposable
二元的銷毀者的 .dispose()
方法一一銷毀. 方法實現(xiàn)前面提到.
至此整個流程走完. 最值得一提的是
我們在 RxSwift 的世界里最重要的東西 -- 管道
sink
,我們就是通過銷毀sink
中保存的屬性以及關聯(lián) 來實現(xiàn)銷毀響應流程.