You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxSwift判断Observable是否已被dispose及移除.debug后失效问题求解

问题根因

你当前的实现逻辑本身存在错误,靠弱引用持有Observable来判断订阅是否销毁的思路从根上不成立:Observable只是数据流的定义模板,和订阅的生命周期没有绑定关系。
之前保留.debug操作符时能正常运行只是巧合:.debug作为中间操作符会强持有上游的Observable实例,只要订阅还存在,你的弱引用就不会被置空;移除.debug后,你生成的Observable没有任何强引用持有,函数返回后就会立刻释放,所以弱引用直接变成nil。

正确实现方案

RxSwift本身提供了监听订阅销毁事件的能力,你只需要在返回的Observable上追加do(onDispose:)操作符,就可以在消费者dispose订阅时触发回调,完成订阅者列表的清理,不需要轮询判断弱引用状态。

修改后的代码如下:

private class Subscriber {
    let ids: [Int]
    // 用于唯一标识订阅者,方便后续查找移除
    let identifier = UUID()
}
class Publisher {
    private let relay: BehaviorRelay<[Int: Updates]> = .init(value: [:])
    private var subscribers: [Subscriber] = []
    // 增加串行队列保证数组操作线程安全,避免多线程操作崩溃
    private let queue = DispatchQueue(label: "com.publisher.queue")

    func updatesStream(for ids: [Int]) -> Observable<[Updates]> {
        let observable = relay
            .map { map in
                return map
                    .filter { ids.contains($0.key) }
                    .map { $0.value }
            }
            .filter { !$0.isEmpty }
            .asObservable()

        let subscriber = Subscriber(ids: ids)
        // 队列中执行插入操作
        queue.sync {
            subscribers.append(subscriber)
        }
        
        // 追加dispose监听
        return observable
            .do(onDispose: { [weak self] in
                guard let self = self else { return }
                self.queue.sync {
                    self.subscribers.removeAll { $0.identifier == subscriber.identifier }
                }
            })
    }

    private func repeatTimer() {
        let updates: [Updates] = [] // 你的业务逻辑生成updates
        
        // 原有清理逻辑可以完全删除,订阅销毁时会自动清理列表
        relay.accept(updates)
    }
}
注意事项
  • 所有对subscribers数组的增删操作都放在同一个串行队列中执行,避免多线程访问导致的数据竞争崩溃。
  • 如果你的业务场景中需要获取当前有效订阅的ids列表,直接从队列中读取subscribers的ids即可。

内容的提问来源于stack exchange,提问作者Oliver Pearmain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:06:08