序
上篇文章 mojito: 麻烦给我的爱人来一份 RxSwift
没有提及 DisposeBag 回收机制
原因有其二
一是因为
时间太短,我没来及看
二是因为
文章过长,必口腔溃疡
Disposable
话不多说,来的都是回头客
看一下经典案例
let obable = Observable<String>.create { observer -> Disposable in
observer.onNext("dispose") # step1
observer.onCompleted() # step2
return Disposables.create {
print("Disposables 释放") # step6
}
}
_ = obable.subscribe(onNext: { (str) in
print("序列" + str) # step3
}, onError: { _ in
}, onCompleted: {
print("完成回调") # step4
}, onDisposed: {
print("销毁回调") # step5
})
// 打印顺序 序列dispose -> 完成回调 -> 销毁回调 -> Disposables 释放
Q 1: 为什么订阅创建时 闭包返回值是 Disposable 类型 ?
先理清一些概念
Disposable
# 名为 Disposable 的协议,定义一个重要的方法 dispose
public protocol Disposable {
# 处理 回收资源.
func dispose()
}
Disposables
# Disposables 是 结构体
public struct Disposables {
private init() {}
}
# Disposables 扩展 create,返回值 AnonymousDisposable 对象
# 销毁者1
extension Disposables {
public static func create(with dispose: @escaping () -> Void) -> Cancelable {
return AnonymousDisposable(disposeAction: dispose)
}
}
Disposables.create,创建了 匿名销毁者 AnonymousDisposable对象, 将闭包 step6 传入
返回值是 Cancelable类型
# 名为 Cancelable 的协议,继承 Disposable
public protocol Cancelable : Disposable {
# 资源是否被销毁过.
var isDisposed: Bool { get }
}
再看一下 AnonymousDisposable
# 继承了 DisposeBase 和 Cancelable,同时拥有 isDisposed & dispose()
private final class AnonymousDisposable : DisposeBase, Cancelable {
# Disposables.create 创建的闭包
public typealias DisposeAction = () -> Void
private let _isDisposed = AtomicInt(0)
private var _disposeAction: DisposeAction?
# 是否被销毁
public var isDisposed: Bool {
return isFlagSet(self._isDisposed, 1)
}
# 保存闭包
private 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()
}
}
}
}
AtomicInt(0): 继承 NSLock, 赋值原始值为 0
fetchOr 和 isFlagSet 都是 AtomicInt 类 的方法,都是线程安全的
isFlagSet:
func isFlagSet(_ this: AtomicInt, _ mask: Int32) -> Bool {
return (load(this) & mask) != 0
}
# 当 `self._isDisposed` 不为0 的时候,也就是 被销毁过
# 则 isFlagSet 返回 true,即 isDisposed 为true
fetchOr:
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()
let oldValue = this.value
this.value |= mask
this.unlock()
return oldValue
}
# 进行 位运算 | ,只有当第一次为 0 的时候,返回 oldValue 0
# 外界等式 成立
# newValue 为 位运算之后的值 1,下次等式 就不等于 0
# 目的:只销毁一次
dispose()
if let action = self._disposeAction {
self._disposeAction = nil
action()
}
# 临时变量 action 保存 外界闭包
# 外界闭包 置nil
# 执行闭包
到这里,我们小结一下
- 小结
Disposables.create是_subscribeHandler闭包执行回调时,开始执行的- 当 执行
_subscribeHandler,势必产生一个匿名销毁者AnonymousDisposable AnonymousDisposable实例,持有外界销毁闭包AnonymousDisposable,具有销毁的能力且只会销毁一次,以及是否销毁的判断
销毁者继承链如下:

Disposables
看到这里就产生了第二个问题
Q 2: dispose什么时候调用 ?
时间回溯到 上篇的 subscribe
public func subscribe(onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
let disposable: Disposable
# 将外界传入的 onDisposed 闭包 , 即 print("销毁回调")
# 生成 匿名销毁者 AnonymousDisposable 实例
if let disposed = onDisposed {
disposable = Disposables.create(with: disposed)
} else {
disposable = Disposables.create()
}
let observer = AnonymousObserver<Element> { event in
switch event {
...省略
case .error(let error):
disposable.dispose()
case .completed:
disposable.dispose()
}
}
# 又 return 一个 Disposables.create
return Disposables.create(
self.asObservable().subscribe(observer),
disposable # 销毁者2 onDisposed
)
}
不难看出,外界调用 subscribe 的时候,将 onDisposed 闭包传入
而 subscribe 的返回值 也是 Disposable类型,也是通过 Disposables.create 返回
定睛一看
这个 Disposables.create, 有2个参数

奇怪的事情发生了
点进去
extension Disposables {
# 通过2个销毁者 ,生成一个新的销毁者
public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
}
不是看在一个爹的份上,你祖坟今天可能没了
Disposables.creat 销毁者1 说到
BinaryDisposable 销毁者,和之前分析的 AnonymousDisposable 如出一辙,这里就不分析了
private final class BinaryDisposable : DisposeBase, Cancelable {
....
# 只是内部多了一个参数
var isDisposed: Bool {
return isFlagSet(self._isDisposed, 1)
}
func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
self._disposable1?.dispose()
self._disposable2?.dispose()
self._disposable1 = nil
self._disposable2 = nil
}
}
}
问题又来到了这个 二元销毁者 的第一个参数 self.asObservable().subscribe(observer)
可以在 Producer中 找到它的身影
override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
# 管道清洁工
# 返回一个 disposer 实例,在它释放时,释放管道内 所有引用
let disposer = SinkDisposer()
# 把 disposer 和 订阅者 传入 序列AnonymousObservable 的 run 中
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
创建了一个 管道清洁工 SinkDisposer 实例 disposer ,通过调用 AnonymousObservable 的 run,将生成的 sink 和 subscription分别持有
并返回 disposer
AnonymousObservable 中
final private class AnonymousObservable<Element>: Producer<Element> {
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
# 通过上面传入的 销毁者,和订阅者 生成匿名观察管道
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
# 调用run ,也就是 执行 _subscribeHandler 闭包 ,将返回值 赋值给subscription
# subscription 指的是 销毁者1
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
AnonymousObservableSink 继承于 Sink,Sink 同样继承于 Disposable,代表了 AnonymousObservableSink 同样具有 dispose() 的能力
老师,我晕了
能不能把 DisposeBag 先给我
我吐一下

Q 3: AnonymousObservableSink 和 SinkDisposer 之间的关系是什么?
A 3: SinkDisposer 将自己的实例,通过匿名观察序列,传入 管道 AnonymousObservableSink 中,管道 Sink 拥有最终解释权
意味着当外界执行订阅subscribe的时候, 会creat 一个 Disposables 元祖
Disposables 元祖内包含 :
- onDisposed 销毁者2
- 管道清洁工 SinkDisposer
- sink
- AnonymousObservableSink
- subscription
- 销毁者1
- sink
因为加入了 Sink 的概念,Sink 作为转换者,处理了 序列 和订阅者 以及 销毁者之间的联系
如果把 Sink 比作 一栋大厦
那 SinkDisposer 就是大厦内的清洁工 ,SinkDisposer 负责处理大厦一切 杂物,但调度能力及解释权还是归大厦 Sink 所属
SinkDisposer
private final class SinkDisposer: Cancelable {
private enum DisposeState: Int32 {
case disposed = 1
case sinkAndSubscriptionSet = 2
}
# 初始值为 0
private let _state = AtomicInt(0)
private var _sink: Disposable?
private var _subscription: Disposable?
# 外界先设置 setSinkAndSubscription
func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {
self._sink = sink
self._subscription = subscription
# 0 | 2 ,第一次返回oldValue 0,previousState 为 0
# _state 赋值为 2
let previousState = fetchOr(self._state, DisposeState.sinkAndSubscriptionSet.rawValue)
# 第一次 previousState 为0, 0 & 2 = 0,继续走
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
rxFatalError("Sink and subscription were already set")
}
# 0 & 1 = 0,不进 if
if (previousState & DisposeState.disposed.rawValue) != 0 {
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
}
}
# 销毁时调用,上面方法已走过一次
func dispose() {
# 在初次调用 setSinkAndSubscription 后, _state 为2, 2 | 1 = 3, fetchOr 返回旧值 2 ,_state 变为 3
# previousState 为 2
let previousState = fetchOr(self._state, DisposeState.disposed.rawValue)
# 2 & 1 = 0,不进 if, 继续走
if (previousState & DisposeState.disposed.rawValue) != 0 {
return
}
# 2 & 2 = 2, 满足条件,进 if ,分别 dispose
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
# AnonymousObservableSink 调用 dispose
sink.dispose()
# 销毁者1 调用 dispose
subscription.dispose()
# 销毁后,分别置nil
self._sink = nil
self._subscription = nil
}
}
}
Q A
Q 1: 为什么订阅创建时 闭包返回值是 Disposable 类型 ?
Disposable 类型 指的是 匿名销毁者,
即销毁者1。因为想在序列创建的时候,就给它挖好坟墓,立好墓碑
如 烬 所说
我于杀戮之中盛放,亦如黎明中的花朵
死不重要,帅就完事了
Q 2: dispose什么时候调用 ?
在本文中,显式调用了 onCompleted,即 执行 subscribe 的 onCompleted闭包,并且接着 调用
disposable.dispose()
case .completed:
onCompleted?()
disposable.dispose() # 销毁者2
}
即 打印顺序为 完成回调 -> 销毁回调
而 此时的 发出onCompleted 信号,必然会顺着 水管 流到 AnonymousObservableSink,调用 sink 的on,即
case .error, .completed:
if fetchOr(self._isStopped, 1) == 0 {
self.forwardOn(event)
self.dispose() # 调用父类 Sink 的 dispose,父类调用 SinkDisposer 的 dispose
}
}
那么这时 SinkDisposer 就会对 sink 和 销毁者1 ,进行销毁
所以最后打印 销毁者1 的 闭包 -> Disposables 释放
执行顺序细节
这里衍生出 Q 4: 如果不显 式 调用 onCompleted 呢? 改为
let obable = Observable<String>.create { observer -> Disposable in
observer.onNext("dispose")
// observer.onCompleted()
return Disposables.create {
print("Disposables 释放")
}
}
let dispose = obable.subscribe(onNext: { (str) in
print("序列" + str)
}, onError: { _ in
print("错误回调")
}, onCompleted: {
print("完成回调")
}, onDisposed: {
print("销毁回调")
})
# 显式调用 dispose
dispose.dispose()
这时候就会先调用 SinkDisposer 的dispose, 元祖 BinaryDisposable 大家还记得吧,SinkDisposer 会先调用,而销毁者2 onDisposed 后调用
所以打印为 序列dispose -> Disposables 释放 -> 销毁回调
Q 4 都有了 Q 5 还会远吗?
Q 5: 为什么调用了 dispose 就可以销毁 响应了呢?
因为 我们销毁了 Sink,销毁了大厦,销毁了通信管道,销毁了外卖小哥送外卖的地址
还怎么响应呢 ?
当然了,序列 和 观察者,终究是 iOS 里面的 平凡的实例对象,会随着控制器的生命周期而销毁
听到这里
懂了的扣 1
不懂的扣脚

DisposeBag
RxSwift 还有一种垃圾回收方式, DisposeBag 可以称之为 垃圾袋
可以把它想象成 一个 autoReleasePool
里面装满了销毁者
随着你把 DisposeBag 扔进垃圾桶,也就是控制器的生命周期结束
里面的销毁者也就逐一销毁
rx.disposeBag
因为 NSObject+Rx 对 垃圾袋 进行了优雅的拓展 ,我们不需要自己创建 disposeBag 了
viewModel.title.asDriver()
.drive(titleLabel.rx.text)
.disposed(by: rx.disposeBag)
# 只需调用 rx.disposeBa 即可
# pod 'NSObject+Rx', '~> 5.0' # https://github.com/RxSwiftCommunity/NSObject-Rx
感兴趣的可以自己看一下 rx.disposeBag 的源码
完
以上是我对 DisposeBag 的理解,还请不吝指正
希望你喝完这 2杯 mojito 味道的 RxSwift 之后
不再需要垃圾袋