任何对象都有生命周期,有创建就要销毁。 OC
中有init
和dealloc
,swift
有init
和deinit
,RxSwift
也不例外,RxSwift
有create
和dispose
。下面就看看dispose
是如何管理序列销毁的。
一篇没有配图的文章是没有灵魂的😂
disposable.png通过前面了解了RxSwift
的两种清除方式:
- 订阅产生的可清除资源(
Disposable
)对象,调用dispose
方法清除 - 通过清除包
DisposeBag
清除,在作用域结束后被释放,也可以在需要的时候置空释放
无论哪种方式,最终都是调用dispose()
方法来释放。
下面看一段序列由创建到销毁:
//创建一个序列
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()
此处代码,我们调用了dispose
方法来销毁对象,销毁者dis
其实和创建序列时返回的Disposables
对象并不是一个对象。
disposable
对象创建代码:
extension Disposables {
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 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()
}
}
}
}
- 初始化保存业务层,创建销毁者对象实现的闭包
-
dispose()
为销毁方法,该方法调用后就销毁了传入的闭包对象 - 判断实列是否被释放,未释放就执行执行对保存闭包的置空操作
-
action()
通知业务层释放监听闭包,通知完成出{}作用域action
即被释放
再看看订阅者中的销毁者的创建(代码标记为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
外部实现的销毁者闭包,实现即传入闭包,否则直接调用create()
创建,目的是对外发出销毁通知 - 最后又创建了一个销毁者对象并返回,可在业务层做销毁操作,该销毁对象保存了
self.asObservable().subscribe(observer)
返回的销毁者,和当前方法中创建的销毁者。what???搞毛啊,这么多销毁者,怕我还不够迷糊吗!!
销毁者Disposables
有多种扩展,为满足不同需求:
- 需要在序列创建处观察销毁情况;
- 前面几篇文章有讲到,在调用
onError
,onCompleted
方法会销毁我们的序列,在业务层省去了开发人员去销毁序列的步骤; - 根据不同业务需求,需要满足开发人员销毁序列的功能。
因此以上出现了这么多的销毁者,最终销毁者还是被同类销毁者(不同扩展)所管理。看一下最后一个销毁者内部做了哪些事情:
extension Disposables {
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
}
- 收集前面所创建的销毁者到
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
协议,并实现了协议方法dispose()
该类中实现了dispose()
方法,该方法即是外部订阅后调用的dispose()
方法,销毁所有创建序列时产生的销毁者,销毁之前各自掉用各自的dispose
方法,来销毁外界保留的闭包对象,并向业务层发送销毁通知。
下面看一下代码1️⃣处self.asObservable().subscribe(observer)
的销毁者是如何产生的:
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
,在该处创建了一个SinkDisposer
对象,应该又是一个销毁者:
fileprivate final class SinkDisposer: Cancelable {}
- 继承自
Cancelable -> Disposable
,并实现了dispose()
方法 - 销毁者去向
run -> AnonymousObservableSink -> Sink
-
Sink
继承自Disposable
,实现了dispose()
方法,内部调用了外部传入的销毁者即SinkDisposer
对象
setSinkAndSubscription
该方法传入了sink
销毁者和业务层创建序列时创建的销毁者。代码如下:
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
创建的销毁者、业务层创建的销毁者),这个地方其他的没干就是想销毁这两个销毁者:
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
置空前都调用了dispose()
,这里面置空销毁者,并向业务层发送了销毁通知。
sink
主要用来连接序列,触发序列闭包,向观察者发送消息。而sink
清空所有内部销毁者后并置空,序列和订阅者就失去联系。
系统销毁:
AnonymousObservableSink
->Sink
->dispose()
->SinkDisposer
->dispose()
外部销毁:
BinaryDisposable
->AnonymousObservableSink
->Sink
->dispose()
->SinkDisposer
->dispose()
无论是系统销毁,还是外部调用dispose
销毁最终所有产生的销毁者都会被销毁释放。到此我们发现我们所销毁的居然是外部对应的监听闭包,内部创建的Disposable
的子类对象。
sink
连接了序列和订阅者,sink
本身是Disposable
对象,因此被销毁后断开了序列和订阅者之间的联系。
网友评论