任何對象都有生命周期,有創(chuàng)建就要銷毀。 OC
中有init
和dealloc
,swift
有init
和deinit
,RxSwift
也不例外,RxSwift
有create
和dispose
。下面就看看dispose
是如何管理序列銷毀的。
一篇沒有配圖的文章是沒有靈魂的??
通過前面了解了RxSwift
的兩種清除方式:
- 訂閱產(chǎn)生的可清除資源(
Disposable
)對象,調(diào)用dispose
方法清除 - 通過清除包
DisposeBag
清除,在作用域結束后被釋放,也可以在需要的時候置空釋放
無論哪種方式,最終都是調(diào)用dispose()
方法來釋放。
下面看一段序列由創(chuàng)建到銷毀:
//創(chuàng)建一個序列
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
方法來銷毀對象,銷毀者dis
其實和創(chuàng)建序列時返回的Disposables
對象并不是一個對象。
disposable
對象創(chuàng)建代碼:
extension Disposables {
public static func create(with dispose: @escaping () -> Void) -> Cancelable {
return AnonymousDisposable(disposeAction: dispose)
}
}
- 實質(zhì)上創(chuàng)建了一個
AnonymousDisposable
類型的銷毀者對象 - 傳入了業(yè)務層的監(jiān)聽閉包,銷毀對象時用來通知
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è)務層,創(chuàng)建銷毀者對象實現(xiàn)的閉包
-
dispose()
為銷毀方法,該方法調(diào)用后就銷毀了傳入的閉包對象 - 判斷實列是否被釋放,未釋放就執(zhí)行執(zhí)行對保存閉包的置空操作
-
action()
通知業(yè)務層釋放監(jiān)聽閉包,通知完成出{}作用域action
即被釋放
再看看訂閱者中的銷毀者的創(chuàng)建(代碼標記為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
外部實現(xiàn)的銷毀者閉包,實現(xiàn)即傳入閉包,否則直接調(diào)用create()
創(chuàng)建,目的是對外發(fā)出銷毀通知 - 最后又創(chuàng)建了一個銷毀者對象并返回,可在業(yè)務層做銷毀操作,該銷毀對象保存了
self.asObservable().subscribe(observer)
返回的銷毀者,和當前方法中創(chuàng)建的銷毀者。what???搞毛啊,這么多銷毀者,怕我還不夠迷糊嗎!!
銷毀者Disposables
有多種擴展,為滿足不同需求:
- 需要在序列創(chuàng)建處觀察銷毀情況;
- 前面幾篇文章有講到,在調(diào)用
onError
,onCompleted
方法會銷毀我們的序列,在業(yè)務層省去了開發(fā)人員去銷毀序列的步驟; - 根據(jù)不同業(yè)務需求,需要滿足開發(fā)人員銷毀序列的功能。
因此以上出現(xiàn)了這么多的銷毀者,最終銷毀者還是被同類銷毀者(不同擴展)所管理。看一下最后一個銷毀者內(nèi)部做了哪些事情:
extension Disposables {
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
}
- 收集前面所創(chuàng)建的銷毀者到
BinaryDisposable
對象中
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é)議,并實現(xiàn)了協(xié)議方法dispose()
該類中實現(xiàn)了dispose()
方法,該方法即是外部訂閱后調(diào)用的dispose()
方法,銷毀所有創(chuàng)建序列時產(chǎn)生的銷毀者,銷毀之前各自掉用各自的dispose
方法,來銷毀外界保留的閉包對象,并向業(yè)務層發(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)建了一個SinkDisposer
對象,應該又是一個銷毀者:
fileprivate final class SinkDisposer: Cancelable {}
- 繼承自
Cancelable -> Disposable
,并實現(xiàn)了dispose()
方法 - 銷毀者去向
run -> AnonymousObservableSink -> Sink
-
Sink
繼承自Disposable
,實現(xiàn)了dispose()
方法,內(nèi)部調(diào)用了外部傳入的銷毀者即SinkDisposer
對象
setSinkAndSubscription
該方法傳入了sink
銷毀者和業(yè)務層創(chuàng)建序列時創(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
}
}
保存了兩個銷毀者(Producer
創(chuàng)建的銷毀者、業(yè)務層創(chuàng)建的銷毀者),這個地方其他的沒干就是想銷毀這兩個銷毀者:
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
置空前都調(diào)用了dispose()
,這里面置空銷毀者,并向業(yè)務層發(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)生的銷毀者都會被銷毀釋放。到此我們發(fā)現(xiàn)我們所銷毀的居然是外部對應的監(jiān)聽閉包,內(nèi)部創(chuàng)建的Disposable
的子類對象。
sink
連接了序列和訂閱者,sink
本身是Disposable
對象,因此被銷毀后斷開了序列和訂閱者之間的聯(lián)系。