RxSwift中Subject.isDisposed未反映实际状态?是否为预期行为?
这属于预期行为,核心原因是混淆了「订阅生命周期」与「Observable本身生命周期」
关键概念区分
- 订阅Disposable:调用
Observable.subscribe()返回的对象,控制的是当前订阅关系的生命周期。dispose它只会取消这个订阅,不会改变Observable本身的状态。 - Observable本身的dispose:只有直接调用
Observable.dispose()时,才会将Observable标记为isDisposed = true,此时该Observable的所有后续订阅都会直接收到completed事件。
对应你的代码与日志分析
flatMapLatest切换时的行为
- 当
upstream.onNext(2)触发时,flatMapLatest会dispose掉上一个内部Observable(第一个PublishSubject对应的订阅Disposable),这个操作仅取消对该PublishSubject的订阅,不会调用它的dispose()方法,因此它的isDisposed仍为false。 - debug操作符打印的
-> isDisposed,指的是debug操作符对应的订阅Disposable被释放,并非PublishSubject本身被dispose。 do(onDispose:)的闭包绑定在订阅Disposable上,当订阅被dispose时触发,此时PublishSubject本身未被dispose,所以打印newSubject.isDisposed = false。
- 当
断言失败的原因
你的两个断言都是检查PublishSubject本身的isDisposed属性,但从始至终你都没有主动调用过newSubject.dispose(),因此无论是第一个还是最后一个PublishSubject,isDisposed都会保持false,导致断言失败。
验证修改示例
如果要让断言通过,需在onDispose中主动dispose Observable本身:
.flatMapLatest { _ in let newSubject = PublishSubject<String>() subjects.append(newSubject) return newSubject.debug("\(Unmanaged.passUnretained(newSubject).toOpaque())").do(onDispose: { newSubject.dispose() // 主动触发Observable本身的dispose print("onDispose :: ", newSubject.isDisposed) // 此时会打印true }) }
内容的提问来源于stack exchange,提问作者funct7
相关产品推荐
相关产品推荐

