问题描述
我在ViewController中有一个PublishSubject<InfoData>
。我订阅了它,所以当它发出一个事件时,我将显示UIAlertViewController。
let infoData = PublishSubject<InfoData>()
private func bindInfoData() {
infoData.subscribe(onNext: { [weak self] (title,message) in
self?.presentInfoSheetController(with: title,message: message)
}).disposed(by: disposeBag)
}
在ViewController中,我有一个带有部分标题的tableView。节标题视图具有infoMessageAction: PublishSubject<InfoData?>
。为viewForHeaderInSection
启动视图时,我在infoMessageAction
和infoData
之间进行了预订。
func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
let view = FutureSpendingsHeaderView(frame: frame)
view.infoMessageAction
.compactMap { $0 }
.bind(to: infoData)
.disposed(by: view.disposeBag)
return view
}
当头视图首次启动时,一切正常-infoMessageAction
触发infoData
,这反过来又触发AlertViewController的显示。
当我将标题视图滚动到屏幕之外时,view.infoMessageAction
和infoData
之间的订阅将被处理(这是在取消初始化视图时的预期行为)。
但是我也处理了infoData
和ViewController之间的订阅。我收到event completed
dispose
订阅的view.infoMessageAction
和infoData
,还有event completed
的dispose
和infoData
ViewController订阅。
我希望只有view.infoMessageAction
infoData
订阅会中断。同样,两个订阅都由不同的disposeBag处理。为什么infoData
ViewController订阅会被处置以及如何阻止它?
谢谢!
解决方法
发现问题,如果有人遇到这种情况。
在节标题视图中,我将disposeBag
初始化为常量,并认为在初始化视图时,其他所有事情都由RxSwift本身处理。
所以我将视图更新为:
var disposeBag = DisposeBag()
deinit {
disposeBag = DisposeBag()
}
现在可以根据需要处置订阅。
, FutureSpendingsHeaderView
被取消初始化时,infoMessageAction
来源的任何视图也被取消初始化,并且该视图在该时间发出completed
事件。该完成的事件将传递到infoData
,然后发出自己的完成事件。
一旦一个Observable发出一个完成的事件,它就完成了。它不能再发出任何事件。因此,对它的订阅已被处理。
您的答案@Alex通过更改视图中事物被取消初始化的顺序来更改方程式。现在首先要对DisposeBag进行初始化,这会在视图发送完成事件之前中断可观察的链。
更好的解决方案是使用PublishRelay
而不是PublishSubject
。中继不会发出完成的事件。
比那更好的是完全摆脱该主题并做类似的事情:
func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
let view = FutureSpendingsHeaderView(frame: frame)
view.infoMessageAction
.compactMap { $0 }
.subscribe(onNext: { [weak self] (title,message) in
self?.presentInfoSheetController(with: title,message: message)
})
.disposed(by: view.disposeBag)
return view
}