RxSwift学习-14-disposable销毁者

1,094 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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()

打印结果

image.png

主动调用,就可以发现结束了序列。但是我们通常会使用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。打印结果

image.png

我们来分析下原理

2. Disposable

我们在订阅subscribe的时候会返回Disposable类型

image.png

看下Disposable,它是一个协议,提供了一个方法dispose,因此我们订阅的返回的对象可以调用dispose()

image.png

在之前我们分析订阅的时候并没有详细说明dispose

image.png

这里就是我们在订阅的时候是否有onDisposed的闭包,有的话我们创建的disposable的时候传入否则默认初始化。

  • Disposables image.png 对于Disposables来说就是一个存放我们用于通用一次性操作的实用方法集合。通常会在拓展中加入自定义的初始化存放我们的onDisposed的闭包等。

image.png

  • AnonymousDisposable

image.png 其中最主要的就是使用dispose()的销毁方法,和初始化保存我们的闭包action

image.png AnonymousDisposable继承DisposeBase主要它的引用计数

image.png Cancelable主要是获取是否正在销毁dispose同时遵循了Disposable协议可以实现dispose()

image.png

继续往下看当我们观察者发送completederror事件的时候就会主动调用dispose()我们实现onDisposed的闭包的话就会调用。

image.png

关于Disposables可以发现它有很多初始化的方法,最后都是返回一个Cancelable,上面我们有看它,主要是判读isDisposeddispose()

image.png

最后我们会把我们的序列订阅产生的Disposable 和我们自己创建的disposable重新生成一个Cancelable类型

image.png

都是Disposable类型。 image.png 当我们调用dispose的时候就会判读当前disposable的销毁状态,处理我们传入的2个Disposable的销毁方法同时置空

image.png

我们在创建的时候实现闭包,销毁的时候就是对应的disposeale1

image.png

image.png

3. SinkDisposer

通过上面的分析其实已经差不多了,但是实际上来说我们序列观察者都是自身创建的对象,那么它实际上来说它的生命周期其实由函数的范围决定的,而不是我们的dispose方法。那么怎么做,我们之前订阅的时候通过sink关联观察者和序列。那么其实我们只要销毁这个sink那么他们之间的关联就断开了,就无法通信了。

image.png

订阅的时候会创建一个SinkDisposer,用它管理我们的sink

image.png 可以发现生成一个元组存放我们的sink和SinkDisposer,之后设置setSinkAndSubscription,保存。

image.png

之后我们调用dispose的时候就会来到具体实现

image.png

把管子sinknil。这样序列和观察者无法通信了。

4.DisposeBag

对应disposeBag我们销毁的时候

image.png

会把我们加入的disposables遍历调用dispose(),达到我们主动调用的效果

5. 总结

对于销毁者我们可以发现订阅序列返回的是Disposable类型,因此我们可以主动调用dispose(),而dispose()来说本质就是销毁sink,也就是我们的管家,从而让序列和观察者无法通信。对于序列和观察者的生命周期应该是他们自己管理,很巧妙的设计。