DisposeBagのRxSwiftのコードをみてみました。
Disposable
dispose(廃棄)できる。
public protocol Disposable {
func dispose()
}
DisposeBagに入れておく。
extension Disposable {
public func disposed(by bag: DisposeBag) {
bag.insert(self)
}
}
DisposeBag
publicメソッドはinsertしかない。DisposeBagがdeinitしたときに持っているDisposableを廃棄してくれる。
public final class DisposeBag: DisposeBase {
private var _lock = SpinLock()
// state
// 登録されたDisposable達
private var _disposables = [Disposable]()
// 廃棄フラグ 廃棄されると立つ
private var _isDisposed = false
public override init() {
super.init()
}
/// bagにDisposableをいれる。すでに廃棄フラグがたっている場合、すぐにdisposeする。
/// - parameter disposable: Disposable to add.
public func insert(_ disposable: Disposable) {
_insert(disposable)?.dispose()
}
/// Disposableを入れる。すでに廃棄フラグがたっていたら素通りする。廃棄フラグがたっていない場合はbagに入り、nilがかえる。
private func _insert(_ disposable: Disposable) -> Disposable? {
_lock.lock(); defer { _lock.unlock() }
if _isDisposed {
return disposable
}
_disposables.append(disposable)
return nil
}
/// 内部的に利用、使いたい場合は代わりにCompositeDisposableを使うこと。
/// 所持しているすべてのDisposableを廃棄処理する。
private func dispose() {
let oldDisposables = _dispose()
for disposable in oldDisposables {
disposable.dispose()
}
}
/// キャッシュしているDisposableを取得、このメソッドではdispose(廃棄)をしていない。
private func _dispose() -> [Disposable] {
/// スピンロックをかける。
_lock.lock(); defer { _lock.unlock() }
/// 登録しているDisposable達
let disposables = _disposables
/// 登録しているDisposableを除く
_disposables.removeAll(keepingCapacity: false)
/// 廃棄したフラグをたてる
_isDisposed = true
/// 除いたDisposable
return disposables
}
/// deinit時に廃棄してくれる。
deinit {
dispose()
}
}