上篇文章 mojito: 费事给我的爱人来一份 RxSwift

没有提及 DisposeBag 收回机制

原因有其二

一是由于

时间太短,我没来及看

二是由于

文章过长,必口腔溃疡

Disposable

话不多说,来的都是回头客

看一下经典事例u I r

let obable = Observable<String>.create { observe| : r $ h 8 ?r -> Disposable in
observer.onNext("dispose")   # step1! D h
observerj : L ~ [.onCompleted()       # step2
return Disposables.crek m F 4 y Bate {
print("Dispok A = 9sables 开释") # step6
}M ` U D B h
}
_ = obable.subscribe(onNext: { (str) in
print("序列" + s2 ] _tr) # sn | j d l U G 3 8tep3
}, onError: { _ in
}, onCompleted: {
print("完结 . = o 1 ^ 8回调")   # step4
}, onDisposed: {
print("毁掉回调")   # step5
})
// 打印次序 序列dispose -> 完结回调 -&g  k M D = .t; 毁掉回调 ->  Disposables 开释

Q 1: 为什么订阅创立时 闭包回来值是 Disposable 类型 ?

先理清一些概念

Disposable

# 名为 Disposable 的协议,界V p F I ] ! 6  u说一个重要的办法 dispose
public protocol Disposable {
# 处理 收回资源.
funn Z L N g Rc disposeg # W C ; 0 y()
}

Disposables

# Disposables 是 结构体
public struct Disposables {[ m w /
private init() {}
}
# Disposables 扩展 create,回来值 AnonymousDisposable 目标
# 毁掉者1
extension Disposables {z Q o E
public static func crev Y gate(with dispose: @escaping () -&gU * K B m d j T @t; V{ % s f K }oid) -> Cany x U + ~ 5 @ !celable {
return AnonymousDisposable(disposeAction: dispose)
}
}

Disposables.c- L | T k & A 7 .reate,创立了 匿名毁掉者 AnonymousDisposable目标, 将闭包 stez : _ ^ D R u ~p@ D U x z6 传入

回来值是 Cancelable类型

# 名为 Cancelable 的协议,承继 Disposable
public protocol Cancelable : Disposable {
# 资源是否被毁掉过.
var isDisposed: Bool { get }
}

再看一下 AnonymousDisposable

# 承继了 DisposeBase 和 Cancel/ Q . 8able,K Y J同时具有  isDisposed &  dispose()
private final class Anony` # A n 5 ] ~ ] tmousDisposable : DisA d K 2poseBase, Cancelable {
# Disposables.crea_ r E q 4 m = bte 创立的闭包
public typealias DisposeAction = () -> Void
private let _isDisposed = AtomicInt(0)
priq N 6 { ^ . 5 DvaR i -te var _disposeActg / : (ion: DiI 8 O c GsposeAction?
# 是否被毁掉
public vl I z - N jar isDisposed: Bool {
return isFlagSet(self._isDisposed, 1)
}
# 保存闭包
private init(_ disposeAction: @escaping DisposeAction) {
self._disposeAction = disposeAction
super.init()
}
# 核心办法  私有仅供自己运用
fileprivate fu( T A _ # : E anc dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
if let action = self._disposeAction {
self._dispoH u -seAction = n# ( ? B * } vil
action(H C G ) K ( G ! w)
}
}
}
}

Atomicg _ 8 u 2 1 p hInt(0)~ = Y 承继 NSLocI & +k, 赋值原始值为 0

fetchOrisFlagSet 都是 AtomicInt 类 的办法C ? 9 G 8,都是线程安全

isFlagSet

func isFlagSet(_ thK B ? 2 . k [ kis: AtomicInt, _ mask: Int32) -> Bool {
return (load(this) & mask) != 0
}
# 当 `) P _ D `self._isDisposed` 不为0 的时分,也便是 被毁掉过
# 则  isFlagSet 回来 true,即 isDisposed 为true 

fetchOr

func fetchOrO & F j H m(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()p P m Y q
let oldValue = this.value
this.value |= mask
this.unlock()
return old/ ; K I F I - ,Value
}
# 进行 位运算 | ,只有当第一次为 0 的时分,回5 r y来 oldVal6  | Q h 3 V ue 0 
# 外界等式 成立
# newValue 为 位运算之后的值 1,下次等式 就不等于 0 
# 目的:只毁掉一次

dispose()

if let action = self._disposeAction {
self._disposeAction = nil
action()
}
# 临时变量 act; Y k ,ion 保存 外界闭包
# 外C f y X ( ~界闭包 置nil 
# 履行闭包

到这儿,咱们小结一下

  • 小结
    • Disposables.create_subscribeHandler闭包履行回调时,开始履行的
    • 当 履行 _subscribeHandler,势必发生一个匿名毁掉d S e v c zAs ~ ` J U s Q & lnonymouP W csDisposable
    • AnonymousDisposable 实例,持有外界 毁掉闭包
    • AnonymousDisp` A mosable,具有 毁掉的才能且只会毁掉一次,以及 是否毁掉的判断

毁掉者承N H g . i F u o继链如下:

RxSwift: 麻烦给我的爱人来一个 DisposeBag

Disposables

看到这儿就发生了第二个问题R Y ( a ~

Q 2: dispose什么时分调用 ?

时间回溯到 上篇的 subscribe

 public func subscribe(onNext: ((Element) -> VoidA l % b)? = nil, onErr C A : O $ . dor: ((Swift.Error) -> Void)? = nil, o9 ? x M ;nCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
let di: l r L 9 ~sposable: Disposable
# 将外r [  ? f U K B界传入的 onDisposed 闭包 , 即 print("毁掉回调") 
# 生成 匿名毁掉者 AnonymousDisposable 实例    
if let disposed = onDisposed {
disposable = Disposables.create(with: disposed)
} else {
disposable = Disposablesm c ^ k.create()& ! G
}
let observer = AnonymousObserver<Element> { event in
switch event {
...省掉
case .error(let error):
disposable.dispose()
case .completed:
disp/ m Qosable.dispose()
}
}
# 又 return 一个 Disposables.create
return Dispq  6 ; c P I Oosables.create(
self.asObservable().subscribe(observer),
disposable # 毁Z s z M I X掉者2 onDisposed
)
}

不难看出,外界调用 subscribe 的时分,将 onDisposed 闭包传入

subscribe 的回来值9 H ) 5 1 q 也是 Disposable类型,也是通过 Disposables.create 回来

定睛一看

这个 Disposables.create, 有2个参数

RxSwift: 麻烦给我的爱人来一个 DisposeBag

古怪的事情发生了

r { : & e |进去

extension Di` Z ( ( csposables {
# 通过2个毁掉者 ,生成一个新的毁掉& + P G [
public static func create(_ disposable1: Disposable, _ disposable2:n h 2 v C j w Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposableq  )2)
}
}

不是看在一个爹的份上,你祖坟今天可能没了

Disposables.creat 毁掉者1 提到

BinaryDisposable 毁掉者,和之前剖# O R M ; #析的 AnonymousDisposable 如出一辙,这儿就不剖析了

private final class BinaryDisposable : DisposeBase, Cancelable {
....
# 只是内部多了一个参数
var isDisposed: Bool {
return isFlagSeY : 7 C (t(self._isDisposed, 1)
}
func dispose() {
if fetchOr(self._isDisposed, 1)` / 8 = == 0 {
self._disposable1?.dispose()
self._disposable2?.dispose()
sb ] [ h Y & N L relf._disposable1 = nil
sB a Xelf._disposable2 = nil
}
}
}

问题又来& h 0 `到了这个 二元毁掉者 的第一个参数 self.asObservable().subscribe(observer)

能够在 Pl _ 4 f m 1roducer中 找到它的身影

override func subscribeH { F @<Obser7 5 5 x 4ver: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
# 管道清洁h Q w p b M - b
# 回来一个 dispof ] Eser 实例,在它开释时,开释管道内 所有引证
let disi { ` l ! m @ poser = SinkDisposer()
# 把 disposer 和 订阅者 传入 序列AnonymousObservable 的 run 中
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(H B 8 ? a l Osink: sinkAndSubscription.sink, subscription: sinkAndSubscriptioh 0 . = I ] r Dn.~ z X r t H G Asubscription)
return disposer
}

创立了一个 管道清洁L $ a P d L E GSinkDisposer 实例 disposer ,通过调用 AnonymousObservable 的 run,将生成的 siL ; Cnksubscription别离持有P { A

并回来 disposer

AnonymousObservable

f{ W j . N D Dinal private class AnonymousObservable<Element>: Producer<Elemeu I : { mnt> {
override func run<Observ# $ j k 9 h 2 e jer~ F p P M: ObserverType>(_ ob ] g 2 [ Fbf g K f S 3 dserver:` u j | 4 k Observer, cancel: Cancelabla | i @ l ! c -e) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
# 通过上面传入的 毁掉者,和订阅者 生成匿名调查管? { X U W y
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
# 调用run ,也便是 履行 _su~ V 9bs/ r F @ ; p ocribeHandler 闭包 ,将回来值 赋值给subscription
# subscription 指的是  毁掉者1
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}

AnonymousObservableSink 承继于 Sink,Sink 同样承继于 Disposable,代表了 AnonymousObservableSink 同样具有 dispose() 的才能

教师,我晕了

能不能把 DispV 3 F o 5oseBag 先给我

我吐一下

RxSwift: 麻烦给我的爱人来一个 DisposeBag

Q 3: AnY J / y o 6 H = xonymousObservableSinkI E RSinkDisposer 之间的关系是什么?

A 3: SinkDisposer 将自己的实例,通过匿名调查序列,传入 管道 AnonymousObservableSink 中,管道 Sink 具有最终解释权

意味着当外界履行订% / P 0subscribe的时+ M C f @分, 会creat 一个 Disposables 元祖

Disposables 元祖内包括 :

  • onDisposed 毁掉者2
  • 管道清洁工 SinkDisposer
    • sink
      • AnonymousObservableSink
    • subscription
      • 毁掉者1

由于加入了 Sink 的概念,Sink 作为转化者,处V x 9 ) g ; h理了 序列 和订阅者 以及 毁掉者之间的联络

假如把 Sink 比作 一栋大厦

SinkDisposer 便是大厦内的清洁工 ,SinkDisposer 负责处理大厦一切 杂物,但调度才能及解释权仍是归大厦 Sink 所属

SinkDisposer

private final class SinkDisposer: Cancelable {
private enum DisposeState: Int32 {
case disposed = 1
case sinkAndSubscriptionSh / [ $  g $et = 2
}
# 初始值为 0
privateQ N Z x 4 b S | let _state = Atom, P PicInt(0)E ) s % n ]
privv N 6 ( 8 R S ate var _sink: Disposabl- : fe?
private var _subscription: Disposable?
# 外界先设置  setp @ : - } @ {SinkAndSubscription
func setSinkAndSubscription(sink: DisposaC ! o sble, subscription: Disposable) {
self._6 W h ; # v } A Fsink = sink
se{ } m w ! a Ilf._subscription = subscription
# 0 | 2 ,第一次回来oldValue 0,previous@ 5 +State 为 0
# _state 赋值为 2
let previousState = fetchOr(self._statX * {e, Dispi 9 M : ; - 3oseState.sinkAndSubscriptionSet.rawValT 4 ) + W zue)
# 第一次  previousState 为0, 0 & 2 = 0,持续走
if (previousState & DisposeState.sinkAndSubscriptionSet.r0 ; 0 + & ;  &awValue) != 0 {
rxFatalError("Sink and subsc w U u Y |ription were alre* Q i #ady set")
}
# 0 & 1 = 0,不进 if
if (previousState & DisposeState.disposed.rawValue) != 0 {
sink.dispose()
subscription.dispo? N t k z D W z Tse()s I j G
self._sink = nil
self._su/ M 3 : { m  Cbscription = nil
}
}
# 毁掉时调用,上面P P 8 V 2 ) ~办法已走过一次
func dispose% u Z() {
# 在初次调用 setSinkAndF I a T 7 $ aSubscription 后,  _@ 0 | O 6 n l +stY o % k & v # Jate 为2, 2 | 1 = 3, fetchOr 回来旧值 2 ,_state 变为 3
# previousState 为 2
let previousState = fetchOr(self._b $ Y 1 n E / * wstate, DisposeSx E @ K * 9 q utate.disposed.rawValue)
# 2 & 1 = 0,不进 if, 持续走
if (previousState & DisposeState.dispB 1 ` O = ; R T Eosed.rawValue) != 0 {
return
}
# 2 & 2  = 2, 满足条件,进 if ,别离 dispose
if (previousState & DisposeState.sinkAndSubscri h J z C : ! +iptionSet.rawValue) != 0 {
# AnonymousObservableS& ! * Z @ink 调用 dispose: B : 2 l
sink.dispose()
# 毁掉者1 调用 df Y r | 3 ; I jispose
subscription.disC 5 q u $pose()
# 毁掉后,别离置nil
self._sink = nil
self._subscription = nil
}
}
}

Q A

Q 1: 为什么订阅创立时 闭包回来值是 Disposable 类型 ?

Disposable 类型 指的是 匿名毁掉者,即毁掉者1u * h ; d w由于想在序列创立的时分,就给它挖好坟墓,立好墓碑

所说

X Q I于杀戮之中盛放,亦如黎明中的花朵

死不重要,帅就完. a m J U { M o事了

Q 2: dispose什么时分调用 ?

在本文中,显式调用了 onCompleted,即 履行 subscribeonCompleted闭包,而且接着 调用

disposa{ N d m eble.dispose()

case .completed:
onCompleted?()
disposable.dispose() # 毁掉者2
}

即 打印次序为 完结回调 -> 毁掉回调

而 此时的 发出onCompleted 信号,必然会顺着 水管 流到 AnonymousObservableSink,调用 sink 的on,即

case .error, .completed] X ^ ^ W .:
if fetchOr(self._isStopped^ o 5 #, 1) == 0 {
self.forwardOn(event)
self.dispose() # 调用父类 Sink 的 dispose,父类调用  SinkDisposer 的 dispose
}
}

那么这时 SinkDisposer 就会对 sink 和 毁掉者1 ,进行毁k n I H X $

所以最终打1 z 9 O G u 9 X L毁掉者1 的 闭包 -> Disposables 开释

履行次序细节

这儿衍生出 Q 4: 假如不显 式 调用 onCompleted 呢? 改为

let obable = Observable<String>.create { obS Q K R w @ [ b hserver -> Disposable in
observer.onNext("dispose")
// observer.onCompleted()
return Disposables.create {
print("Disposables 开释")
}
}
let dispose  = obable.subscribe(onNext: { (str) in
print("序列" + str)
}, onError: { _ in
print("过错回调")
}, onI n ; 6 r CCompleted: {
print("完结l R q c | K回调")
}, onDisposed: {
print("毁掉回# g I 8 J调")
})
# 显式调用 dispose
dispose.dispose(r U D & Q K { [)

这时分就会先调用 SinkDisposer 的dispose, 元祖S ] V 0 r i W BinaryDisposabE J b T 7 le 大家还记得吧,SinkDisposT | E ~ u @er 会先调用,而毁掉者2 onDisposeK . N m n o | nd 后调用

所以打印为 序列dispose -> Disposableo t 2s 开释 -> 毁} ( O j !掉回调

Q 4 都有了 Q 5 还会远吗?

Q 5: 为什么调用了 dispose 就能够毁掉 呼应了呢?

由于 咱们毁掉了 Sink,毁掉了大厦,毁掉了通信管道,毁掉了外卖小哥送外卖的地址

还怎样呼应呢 ?

当然了,序列 和 调查者,终究是 iOS 里边的 普通的实例目标,会跟着控制器的生命周期而毁掉

听到这儿

懂了的扣 1

不明白的扣脚

RxSwift: 麻烦给我的爱人来一个 DisposeBag

Dis4 k = m P 2 ;poseBag

RxSwift 还有一种废物收回方式, DisposeBag 能够称之为 废物袋

能够把它想象成 一个 autl ? E p oReleasePool

里边装满了毁掉者

跟着你把 DisposeBag 扔进废物桶,也便是控制器的生命周期结束

里边的毁掉者也就逐一毁掉

rx.disposeBag

由于 NSo V : 0 6 B , E eObject+Rx 对 废物^ 2 f袋 进行了优雅的= ` n拓展 ,咱们不需要自己创立 disposeBag 了

 viewModel.title.asDriver()
.drive(titleLabel.rx.text)
.dispose( U r A Vd(by: rx.disposeBag)
# 只需调用 rx.disposeBa 即可
# pod 'NSObject+Rx', '~&: o $ ] ) s #gt; 5.0'  # https://github.coI J ^ um/RxSwiftCommunity/NSObject-Rx

感兴趣的能够自己看一下 rx.disposeBag 的源码

以上是我对 DisposeBag 的理解,还请不吝指正

期望你喝完这 2杯 mojito 滋味的 RxSwifK ! Ct 之后

不再需要废物袋