Disposable - 可被清除的资源
error 或者 completed 事件,那么所有内部资源都会被释放。如果需要提前释放这些资源或取消订阅的话,那么可以手动调用 dispose 方法。
下面我们来看一段熟悉的代码(手动调用)
let ob = Observable<Any>.create { (obserber) -> Disposable in
//发送信号
obserber.onNext("马小撂")
return Disposables.create{print("销毁闭包")}
}
//订阅信号
let dispose = ob.subscribe(onNext: { (text) in
print("on next\(text)")
}, onError: { (error) in
print("error")
}, onCompleted: {
print("完成")
}) {
print("销毁回调")
}
dispose.dispose()
-
首先先看
observable的创建,里面返回一个销毁着
Disposables.create{print("dispose销毁")}
点进去看见disposables的创建
public static func create(with dispose: @escaping () -> Void) -> Cancelable {
return AnonymousDisposable(disposeAction: dispose)
}
这里面返回了一个AnonymousDisposable
fileprivate final class AnonymousDisposable : DisposeBase, Cancelable {
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()
}
}
}
}
AnonymousDisposable初始化的时候保存了一个创建Disposables时的回调闭包,和一个dispose()的方法,解释一下fetchOr方法
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()
let oldValue = this.value
this.value |= mask
this.unlock()
return oldValue
}
this.value 初始化的时候为0,this.value 赋值给 oldValue,然后 this.value 按位或 mask(1),this.value等于1,返会 oldValue(0),再次进来是this.value等于1,返回1不等于0,所有闭包的销毁方法只会执行一次。
-
然后在让我们来看一下序列的订阅,点进
subscribe
public func subscribe(onNext: ((Element) -> 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<Element> { event in
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
)
}
subscriber会创建一个Disposable,如果外界传过来闭包就保存创建,没有就直接创建。在subscriberHandle里面我还可以看见当发送error事件和completed事件时会帮我们调用dispose()。
我们着重来看一下self.asObservable().subscribe(observer),disposable 这句返回Disposables的创建
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
这里面返回了一个二元销毁着BinaryDisposable
private final class BinaryDisposable : DisposeBase, Cancelable {
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
}
}
初始化保存了两个销毁着,并在
dispose()方法中全部销毁置空。
接下来,我们看一下二元销毁着的两个参数是什么,第二个参数非常的直观,就是上面创建保存外界闭包的销毁着,那第一个参数是什么呢?
点击subscribe就会来到父类Producer的subscribe函数,
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
if !CurrentThreadScheduler.isScheduleRequired {
}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
}
}
可以清晰的看到返回的是SinkDisposer,这就是我们二元销毁者的第一个参数。初始化一个SinkDisposer,然后来到run函数。
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)
}
返回一个sink(AnonymousObservableSink) 和subscription(AnonymousDisposable)这个元组,带着这两个参数会来到setSinkAndSubscription函数中
fileprivate final class SinkDisposer: Cancelable {
fileprivate enum DisposeState: Int32 {
case disposed = 1
case sinkAndSubscriptionSet = 2
}
private let _state = AtomicInt(0)
private var _sink: Disposable?
private var _subscription: Disposable?
var isDisposed: Bool {
return isFlagSet(self._state, DisposeState.disposed.rawValue)
}
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,因为0按位或为2,但返回的旧值,仍为0,0&其他都是0,所以下面的方法都不走
最后当我们手动调用dispose.dispose()时会发生什么
func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
self._disposable1?.dispose()
self._disposable2?.dispose()
self._disposable1 = nil
self._disposable2 = nil
}
}
我们看到了二元销毁者,逐一的销毁并置nil,先看第一个参数SinkDisposer的销毁
case disposed = 1
case sinkAndSubscriptionSet = 2
func dispose() {
let previousState = fetchOr(self._state, DisposeState.disposed.rawValue)
if (previousState & DisposeState.disposed.rawValue) != 0 {
return
}
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
guard let sink = self._sink else {
rxFatalError("Sink not set")
}
guard let subscription = self._subscription else {
rxFatalError("Subscription not set")
}
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
}
}
经过上次的处理self._state已经为2了:
第一个条件:2 & 1 == 0,不满足,跳过继续下一步。
第二个条件成立:2 & 2 == 2,然后让_sink和_subscription分别去dispose。
AnonymousObservableSink继承于Sink,就会来到Sink的disposed
func dispose() {
fetchOr(self._disposed, 1)
self._cancel.dispose()
}
_sink用fetchOr做了个标记后,让SinkDisposer调用dispose。上次新值value为3了,那它与上任何一个枚举值都是true,所以第一个条件满足,直接return。
然后是_subscription(AnonymousDisposable)的dispose。
fileprivate func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
if let action = self._disposeAction {
self._disposeAction = nil
action()
}
}
}
把销毁回调闭包置为nil,然后执行打印销毁闭包,第一个参数就结束了,然后来看第二个参数就是订阅时初始化的销毁闭包,调用一下就可以了,打印销毁回调。
这个销毁流程,可以看出我们通过销毁
sink,来达到销毁的目的。
error 或者 completed事件会自动调用,但是调用的顺序会有所不同
switch event {
case .next:
if load(self._isStopped) == 1 {
return
}
self.forwardOn(event)
case .error, .completed:
if fetchOr(self._isStopped, 1) == 0 {
self.forwardOn(event)
self.dispose()
}
}
先发送self.forwardOn(event),然后调用self.dispose()
let observer = AnonymousObserver<Element> { 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()
}
}
先调用AnonymousObserver中的闭包,也就是订阅中的回调闭包,然后在调用sink中的闭包。