RxSwift 하나의 구독을 폐기하면 다른 구독의 폐기가 호출됩니다.
나는이 PublishSubject<InfoData>
의 ViewController에. 그리고 나는 그것을 구독하므로 이벤트가 발생하면 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
(뷰가 deinited되면서 예상되는 동작)를 파기합니다.
그러나 infoData
나는와 ViewController 사이의 구독도 폐기했습니다 . 나는 수신 event completed
및 dispose
대한 view.infoMessageAction
<-> infoData
가입 및도 event completed
및 dispose
대한 infoData
<->의 ViewController의 가입이 필요합니다.
view.infoMessageAction
<-> infoData
구독 만 중단 될 것으로 예상합니다 . 또한 두 구독 모두 다른 disposeBag에 의해 처리됩니다. infoData
<-> ViewController 구독이 폐기되는 이유 와이를 방지하는 방법은 무엇입니까?
미리 감사드립니다!
답변
FutureSpendingsHeaderView
초기화가 해제 되면 소스 인 뷰 infoMessageAction
도 초기화 해제되고 해당 뷰 completed
는 해당 시점에 이벤트를 생성합니다. 완료된 이벤트가 전달되어 infoData
자체 완료된 이벤트를 내 보냅니다.
Observable이 완료된 이벤트를 내 보내면 완료됩니다. 더 이상 이벤트를 생성 할 수 없습니다. 따라서 그것에 대한 구독이 폐기됩니다.
귀하의 답변 @Alex는 뷰 내부의 항목이 초기화되지 않는 순서를 변경하여 방정식을 변경합니다. disposeBag는 이제 먼저 초기화가 해제되고 뷰가 completed 이벤트를 보내기 전에 관찰 가능한 체인이 끊어집니다.
더 나은 솔루션은 사용하는 것 PublishRelay
(A)보다 다소을 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
}
누군가가 그러한 상황에 직면하면 문제를 발견했습니다. 섹션 헤더 뷰에서 나는 disposeBag
상수로 시작 했고 뷰가 정의 될 때 다른 모든 것은 RxSwift 자체에서 처리한다고 생각했습니다. 그래서 뷰를 다음과 같이 업데이트했습니다.
var disposeBag = DisposeBag()
deinit {
disposeBag = DisposeBag()
}
이제 구독은 필요에 따라 폐기됩니다.