一、销毁者
在RxSwift
销毁者扮演了很重要的作用,销毁已经完成(completed
)的或者已经错误(error
)的序列。但是如果你需要提前释放这些资源或者取消订阅的话,那么你可以对返回的 Disposable(可被清除的资源) 调用 dispose
方法。 调用 dispose
方法后,订阅将被取消,并且内部资源都会被释放掉。
1.销毁者初探
接下来我们来看一个例子:
//创建序列
self.intervalOB = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.init())
//订阅事件-返回销毁者
let dispose = self.intervalOB.subscribe(onNext: { num in
self.showSencondNum.text = String(num)
print("num=\(num)")
})
_ = self.stopAction.rx.tap.subscribe(onNext: {
print("点击按钮")
dispose.dispose() //执行销毁方法
})
看到例子,1.创建了定时器序列 2.订阅并返回了Disposable(可被清除的资源) 3.点击按钮执行dispose()销毁方法。
运行结果: 我们在看一个例子:
// 创建序列
let ob = Observable<Any>.create { observer -> Disposable in
observer.onNext("NY")
return Disposables.create { print("销毁释放了") }
}
// 序列订阅
let dispose = ob.subscribe(onNext: { anything in
print("订阅到了:\(anything)")
}, onError: { error in
print("订阅到Error:\(error)")
}, onCompleted: {
print("完成了")
}) {
print("销毁回调")
}
NSMutableArray(capacity: 10)//10 扩容10+10 上拉加载更多
print("执行完毕")
dispose.dispose()
看到代码创建序列Observable 中返回了销毁者Disposables.create,然后订阅ob返回Disposable(可被清除的资源),在最后调用dispose.dispose()清理资源。
现在有一个问题Disposables.create返回的是什么?有什么作用?
进入代码一探究竟:
public class DisposeBase {
init() {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
}
deinit {
#if TRACE_RESOURCES
_ = Resources.decrementTotal()
#endif
}
}
//协议类
public protocol Cancelable : Disposable {
/// Was resource disposed.
var isDisposed: Bool { get }
}
public protocol Disposable {
/// Dispose resource.
func dispose()
}
//在子类实现
/// Calls the disposal action if and only if the current instance hasn't been disposed yet.
///
/// After invoking disposal action, disposal action will be dereferenced.
fileprivate func dispose() {
if fetchOr(self.disposed, 1) == 0 {
if let action = self.disposeAction {
self.disposeAction = nil
action()
}
}
}
AnonymousDisposable
基础了DisposeBase基类,并实现了Cancelable
协议方法isDisposed,dispose 。dispose
私有方法不可重写,保存临时action 并销毁self.disposeAction = nil 在执行闭包action()。
继续跟踪代码:
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()
let oldValue = this.value
this.value |= mask // 0000 0000 | 0000 0001 结果是1
this.unlock()
return oldValue
}
判断self.disposed==0时执行并销毁self.disposeAction。
2.销毁的本质
我们运行一下例子二: 从打印的信息上看出,订阅到了消息,执行了执行完毕后dispose.dispose(),在销毁前执行了,释放后在执行了销毁回调。
如果修改代码:
// 创建序列
let ob = Observable<Any>.create { observer -> Disposable in
observer.onNext("NYY-e")
observer.onCompleted()
observer.onNext("XXXX")
return Disposables.create { print("销毁释放了") }
}
////省略代码............////
print("执行完毕")
// dispose.dispose()
从代码上看,onCompleted()后又再次,发送了消息onNext("XXXX"),如果onCompleted 执行完已经销毁了序列,将看不到打印。 和我们的猜想差不多,在onCompleted()之后序列执行完成Completed回调后,销毁回调,在销毁释放了。
问题1:
不执行dispose.dispose(),而执行observer.onCompleted() 的销毁执行顺序是不一样的。
问题2:
为什么会产生这样的差异,第一先执行释放,再销毁回调。第二先回调,再释放。
进入源码一探究竟:
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
BinaryDisposable(disposable1, disposable2)
}
//二元销毁者
private final class BinaryDisposable : DisposeBase, Cancelable {
private let disposed = AtomicInt(0)
// state
private var disposable1: Disposable?
private var disposable2: Disposable?
/// - **returns**: Was resource disposed.
var isDisposed: Bool {
isFlagSet(self.disposed, 1)
}
/// Constructs new binary disposable from two disposables.
///
/// - **parameter** disposable1: First disposable
/// - **parameter** disposable2: Second disposable
init(_ disposable1: Disposable, _ disposable2: Disposable) {
self.disposable1 = disposable1
self.disposable2 = disposable2
super.init()
}
/// Calls the disposal action if and only if the current instance hasn't been disposed yet.
///
/// After invoking disposal action, disposal action will be dereferenced.
func dispose() {
if fetchOr(self.disposed, 1) == 0 {
self.disposable1?.dispose()
self.disposable2?.dispose()
self.disposable1 = nil
self.disposable2 = nil
}
}
}
func dispose() 和AnonymousDisposable
的dispose 基本一样,也是只销毁一次,可以外部调用。
return Disposables.create(
self.asObservable().subscribe(observer),//SinkDisposer
disposable //外界的销毁闭包
)
这个sinkAndSubscription.sink 和 sinkAndSubscription.subscription
的作用是什么?
sinkAndSubscription.sink 就是AnonymousObservableSink
sinkAndSubscription.subscription 就是 Disposable(销毁者)对象处理闭包
所以销毁Sink在Rx世界失去联系,真正要销毁的是RxSwift响应式关系
。
3.垃圾袋销毁流程
看垃圾袋代码:
extension Disposable {
/// Adds `self` to `bag`
///
/// - **parameter** bag: `DisposeBag` to add `self` to.
public func disposed(by bag: DisposeBag) {
bag.insert(self) //添加到垃圾袋
}
}
private func _insert(_ disposable: Disposable) -> Disposable? {
self.lock.performLocked {//递归锁
if self.isDisposed {
return disposable
}
self.disposables.append(disposable)
return nil
}
}
/// This is internal on purpose, take a look at `CompositeDisposable` instead.
private func dispose() {
let oldDisposables = self._dispose()
for disposable in oldDisposables { //遍历销毁
disposable.dispose()
}
}
private func _dispose() -> [Disposable] {
self.lock.performLocked {
let disposables = self.disposables
self.disposables.removeAll(keepingCapacity: false)//移除,不保存当前空间
self.isDisposed = true //设置为已销毁
return disposables
}
}
deinit {
self.dispose() //类销毁时调用
}
DisposeBag->insert(序列)->dispose遍历执行(销毁响应关系)->先保存,在移除removeAll->设置isDisposed = true。
4.总结
Disposable销毁者
:就是创建AnonymousDisposable
中的dispose 基本一样,也是只销毁一次,可以外部调用,sinkAndSubscription 在AnonymousDisposable 订阅中创建,sinkAndSubscription 控制销毁,序列的响应关系。DisposeBag垃圾袋
:就是收集和管理需要释放的序列,(添加到array,遍历释放)就是这样简单的逻辑。