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
จำหน่าย (ซึ่งเป็นพฤติกรรมที่คาดไว้เนื่องจากมุมมองถูกยกเลิก)
แต่ฉันได้ยกเลิกการสมัครสมาชิกระหว่าง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 กำลังถูก deinitialized ก่อนซึ่งจะทำลายห่วงโซ่ที่สังเกตได้ก่อนที่มุมมองจะส่งเหตุการณ์ที่เสร็จสมบูรณ์
ทางออกที่ดีกว่าคือการใช้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
}
พบปัญหาหากใครเผชิญสถานการณ์ดังกล่าว ในมุมมองส่วนหัวของส่วนฉันเริ่มต้นdisposeBag
เป็นค่าคงที่และคิดว่าทุกอย่างอื่นจะถูกจัดการโดย RxSwift เองเมื่อมุมมองถูกยกเลิก ดังนั้นฉันจึงอัปเดตมุมมองเป็น:
var disposeBag = DisposeBag()
deinit {
disposeBag = DisposeBag()
}
ตอนนี้การสมัครสมาชิกจะถูกกำจัดตามความจำเป็น