一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
- 对于RxSwift主要是4个部分,可观察序列
Observable,观察者Observer,调度者scheduler,销毁者disposable。之前我们已经分析了前面3个,这篇文章主要分析disposeale的使用和流程,作用。
1. 使用
如何使用呢?看下下面的例子
- 主动调用
let ob = Observable<Int>.create { observer in
observer.onNext(1)
return Disposables.create()
}
let disposeable = ob.subscribe(onNext: {print($0)}, onError: {print($0)}, onCompleted: {
print("end")
}) {
print("dispose")
}
//主动调用
disposeable.dispose()
打印结果
主动调用,就可以发现结束了序列。但是我们通常会使用disposeBag统一处理
disposeBag我们的序列使用disposeBag统一进行处理
let ob1 = Observable<Int>.create { observer in
observer.onNext(1)
return Disposables.create()
}
let ob2 = Observable<Int>.create { observer in
observer.onNext(2)
return Disposables.create()
}
ob1.subscribe(onNext: {print($0)}, onError: {print($0)}, onCompleted: {print("ob1-completed")}, onDisposed: {print("ob1-disposed")})
.disposed(by: disposeBag)
ob2.subscribe(onNext: {print($0)}, onError: {print($0)}, onCompleted: {print("ob2-completed")}, onDisposed: {print("ob2-disposed")})
.disposed(by: disposeBag)
//点击销毁
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.disposeBag = DisposeBag()
}
我们主动销毁,重设disposeBag。打印结果
我们来分析下原理
2. Disposable
我们在订阅subscribe的时候会返回Disposable类型
看下Disposable,它是一个协议,提供了一个方法dispose,因此我们订阅的返回的对象可以调用dispose()。
在之前我们分析订阅的时候并没有详细说明dispose
这里就是我们在订阅的时候是否有onDisposed的闭包,有的话我们创建的disposable的时候传入否则默认初始化。
Disposables对于
Disposables来说就是一个存放我们用于通用一次性操作的实用方法集合。通常会在拓展中加入自定义的初始化存放我们的onDisposed的闭包等。
AnonymousDisposable
其中最主要的就是使用
dispose()的销毁方法,和初始化保存我们的闭包action。
AnonymousDisposable继承DisposeBase主要它的引用计数。
Cancelable主要是获取是否正在销毁dispose同时遵循了Disposable协议可以实现dispose()
继续往下看当我们观察者发送completed和error事件的时候就会主动调用dispose()我们实现onDisposed的闭包的话就会调用。
关于Disposables可以发现它有很多初始化的方法,最后都是返回一个Cancelable,上面我们有看它,主要是判读isDisposed和dispose()。
最后我们会把我们的序列订阅产生的Disposable 和我们自己创建的disposable重新生成一个Cancelable类型
都是Disposable类型。
当我们调用
dispose的时候就会判读当前disposable的销毁状态,处理我们传入的2个Disposable的销毁方法同时置空。
我们在创建的时候实现闭包,销毁的时候就是对应的disposeale1
3. SinkDisposer
通过上面的分析其实已经差不多了,但是实际上来说我们序列和观察者都是自身创建的对象,那么它实际上来说它的生命周期其实由函数的范围决定的,而不是我们的dispose方法。那么怎么做,我们之前订阅的时候通过sink关联观察者和序列。那么其实我们只要销毁这个sink那么他们之间的关联就断开了,就无法通信了。
订阅的时候会创建一个SinkDisposer,用它管理我们的sink
可以发现生成一个
元组存放我们的sink和SinkDisposer,之后设置setSinkAndSubscription,保存。
之后我们调用dispose的时候就会来到具体实现
把管子sink为nil。这样序列和观察者无法通信了。
4.DisposeBag
对应disposeBag我们销毁的时候
会把我们加入的disposables遍历调用dispose(),达到我们主动调用的效果
5. 总结
对于销毁者我们可以发现订阅序列返回的是Disposable类型,因此我们可以主动调用dispose(),而dispose()来说本质就是销毁sink,也就是我们的管家,从而让序列和观察者无法通信。对于序列和观察者的生命周期应该是他们自己管理,很巧妙的设计。