RxSwift系列—销毁者Dispose

10 篇文章 0 订阅
9 篇文章 3 订阅

七、销毁者Dispose

一般来说,一个可观察序列发出了 error 或者 completed 事件,那么所有内部资源都会被释放。但是如果你需要提前释放这些资源或者取消订阅的话,那么你可以对返回的 Disposable(可被清除的资源) 调用 dispose 方法。 调用 dispose 方法后,订阅将被取消,并且内部资源都会被释放掉。

7.1 案例引入

// 创建序列
let ob = Observable<Any>.create { (observer) -> Disposable in
    observer.onNext("tony")
    return Disposables.create { print("销毁释放了")} // dispose.dispose()
}
// 序列订阅
let dispose = ob.subscribe(onNext: { (anything) in
    print("订阅到了:\(anything)")
}, onError: { (error) in
    print("订阅到了:\(error)")
}, onCompleted: {
    print("完成了")
}) {
    print("销毁回调")
}
// 销毁关系
// status - 算法 - dispose 随时随地都能销毁

// 对象 是无法销毁的
print("执行完毕")
dispose.dispose()
/*
订阅到了:tony
执行完毕
销毁释放了
销毁回调
*/

7.2 基本源码分析

7.2.1 Disposables垃圾袋创建

  • 上面案例代码中关于销毁者相关的就是我们创建序列的回调闭包Disposables.create {print("销毁释放了")} 咱们直接定位到核心代码!看到这段代码,是不是似曾相识!在Observable中也有它!
    在这里插入图片描述
    我们跟一下create 方法

在这里插入图片描述

  • 创建了一个匿名销毁者 AnonymousDisposable 跟我们的序列,订阅者一样的手法,不同的业务逻辑必然还有其他细节操作,但是我们从一般入手快速直接
    在这里插入图片描述
  • 上面我们可以看到初始化就是保存了响应回调闭包,那么在什么时候回调呢?就在下面我们标记的核心逻辑代码 - dispose()
  • fetchOr(self._isDisposed, 1) 是一个单项标记手段,我们一般操作就是属性标记(eg:flag)。
func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
    this.lock()
    let oldValue = this.value  // 0  1
    /// |= 按位或 运算 后再赋值,eg:C |= 2 相当于 C = C | 2
    this.value |= mask    // 1 1
    this.unlock()
    return oldValue  // 0 1 1 1 1 1 1 1
}
/*
 十进制:二进制
    1:  01
    2:  10
 按位或 运算后 -> 11 -> 3
*/

self._isDisposed 值为 AtomicInt(0) 则,this.value = 0mask = 1,那么,最后的返回值为0,且 self._isDisposed 中的 value 变为 1。即这里的 fetchOr 函数仅在第一次执行时返回值为 0,以后均为 1也意味着,dispose() 只会执行一次。

  • 上面方法的意思就是保证只会销毁一次
  • 下面就是对回调闭包取出然后置空销毁 self._disposeAction = nil
  • 对取出的闭包调用执行: action()

现在感觉一切很顺利,但是聪明的我们一定要知道这里落下一个重要的前导因素:什么时候调用了 dispose()

7.2.2 销毁调用

上面的流程,我们是在序列的回调闭包:subscriberHandle里面,其实这个流程之前还有一个非常重要的流程:订阅 subscriber

if let disposed = onDisposed {
  /// 保存垃圾回收袋
  disposable = Disposables.create(with: disposed)  
}else {
  disposable = Disposables.create()
 }
  • 这里就是保存外界销毁闭包的保存 - 达到提示销毁
    在这里插入图片描述
  • 观察者回调里面调用, 响应外界调回闭包
  • return Disposables.create(self.asObservable().subscribe(observer),disposable) 综合来看,我们的重点必然在这句代码,沟通下面流程的 subscribe, 外界订阅返回的销毁者(可以随时随地进行 dispose.dispose()
  • 上面代码跟进去看到BinaryDisposable(disposable1, disposable2) 原来创建的二元销毁者
    在这里插入图片描述
  • 二元销毁者的 dispose 方法也在预料之中,分别销毁
  • 那么我们的重点就应该探索,在 subscribe 这里面创建的关键销毁者是什么?
  • 下面我们进入非常熟悉的:Producer
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink,
 subscription: sinkAndSubscription.subscription)
// 返回销毁者
return disposer
func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {
    self._sink = sink
    self._subscription = subscription

		// 获取状态 
    let previousState = fetchOr(self._state, DisposeState.sinkAndSubscriptionSet.rawValue)
		
		// 如果状态满足就销毁
    if (previousState & DisposeState.disposed.rawValue) != 0 {
        sink.dispose()
        subscription.dispose()
        self._sink = nil
        self._subscription = nil
    }
}
  • 保存了两个属性 : sinksubscription(就是外界创建序列的闭包的返回销毁者)
  • 取了某一个状态:previousState,判断状态的条件,然后执行 这两个保存属性的销毁和置空释放销毁 : .dispose() + = nil

OK 剩下我们还去一个传进去的销毁者,跟一下源码!

// 创建 sink 保存了销毁者
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
// 中间流程省略..
func on(_ event: Event<Element>) {
    switch event {
    case .next:
        self.forwardOn(event)
    case .error, .completed:
        if fetchOr(self._isStopped, 1) == 0 {
            self.forwardOn(event)
            // 关键点:完成和错误信号的响应式必然会直接开启销毁的
            self.dispose()
        }
    }
}
  • 完成和错误信号的响应式必然会直接开启销毁的 : self.dispose()! 这里也解释了:一旦我们的序列发出完成或者错误就无法再次响应了!
  • 剩下一个BIG问题: 到底我们的销毁的是什么
func dispose() {
    let previousState = fetchOr(self._state, DisposeState.disposed.rawValue)

    if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
        sink.dispose()
        subscription.dispose()

        self._sink = nil
        self._subscription = nil
    }
}
  • 无论我们直接销毁还是系统帮助我们销毁必然会调用:dispose()
  • 我们查看 dispose() 得出: 就是在初始化初期我们保留的两个属性的操作
  • sink.dispose() + self._sink = nil & subscription.dispose() + self._subscription = nil 执行相关释放和销毁
  • 我们在 RxSwift 的世界里最重要的东西,我们就是通过:序列,观察者 来建立响应关系!如果我们断开了响应关系不就达到销毁的目标?然而我们断开响应关系最重要的就是:Sink这根管子!

7.3 总结

经过上面的销毁者源码分析,可以知道,销毁者(Disposable)的核心流程主要有3个:

  1. 销毁连接 可观察序列观察者AnonymousObservableSink 对象,打断其中连接,取消订阅。–这也是其核心逻辑
  2. 回调创建序列时返回的Disposables.create{ print("销毁释放了") } 中的闭包。
  3. 回调订阅信号时的 onDisposed 闭包。在这里插入图片描述
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值