>首次订阅,用于在每次点击时更新UI
>第二次订阅,用于在累积点击后每1秒更新一次Web服务上的值.
码:
class ProductionSize { var id : Int? var size: Int = 0 var name: String = "" } class ProductionCell: UICollectionViewCell { var rxBag = DisposeBag() // this will be set in the (cellForItemAt indexPath: IndexPath) of collection view var productionSize: ProductionSize? { didSet { showProductionSize() prepareButton() } } func showProductionSize() { // ... code for showing ProductionSize in labels } func prepareButton() { // This for subscribing for every click for displaying purpose btn_increase.rx.tap .subscribe(){event in self.increaseClicked() } .addDisposableTo(rxBag) // this for subscribing for sending webservice request after 1 second of clicking the button (so that if user click it quickly i send only last request) btn_increase.rx.tap .debounce(1.0,scheduler: MainScheduler.instance) .subscribe(){ event in self.updateOnWS() } .addDisposableTo(rxBag) } func increaseClicked() { productionSize.size = productionSize.size + 1 showProductionSize() } func updateOnWS() { // code for updating on webservice with Moya,RxSwift and Alamofire§ } // when scrolling it gets called to dispose subscribtions override func prepareForReuse() { rxBag = DisposeBag() } }
问题:
由于dispose发生在prepareForReuse()上,如果我多次单击该按钮并立即滚动,webservice调用将被处理掉而不会更新.
我试过的:
>将addDisposableTo(vc?.rx_disposableBag)添加到父ViewController DisposableBag.
问题,订阅累积和每次点击updateWS()多次调用,在每个滚动上订阅,从未处理.
>我试图从prepareForReuse()中删除disposableBag重新初始化.
问题是,每次点击都会调用对重复和累积的按钮的订阅以及许多webservice调用.
题:
如何让debounce订阅调到最后,并且从不重复多次订阅(如果是addDisposableTo viewController Bag)?
解决方法
Added
addDisposableTo(vc?.rx_disposableBag)
to the parent ViewController DisposableBag.The problem,the subscribtions accumulated and on every click the updateWS() called many times which is subscribed on every scroll and never disposed.
由于您订阅按钮的点击方式,您的self.updateOnWS()可能会被多次调用.
btn_increase.rx.tap .debounce(1.0,scheduler: MainScheduler.instance) .subscribe(){ event in self.updateOnWS() } .addDisposableTo(rxBag)
如您所见,您使用subscribe()方法订阅所有事件.这意味着所有Rx事件(onNext,onError,onCompleted,onSubscribed和onDisposed)都会触发self.updateOnWS().您可以通过打印事件对象来检查是否是这种情况,以查看触发了什么事件.
仅在onNext上订阅
可能的修复可能是仅订阅onNext操作.
btn_increase.rx.tap .debounce(1.0,scheduler: MainScheduler.instance) .subscribe(onNext: { [weak self] (_ : Void) in self?.updateOnWS() }) .addDisposableTo(vc?.rxdisposableBag)
通过使用视图控制器的DisposeBag,您可以确保即使单元格被放置(向下滚动时)操作仍然继续.但是,如果在单元格处理时需要它来处置订阅,请使用单元格的DisposeBag,而不是视图控制器.
旁注 – 内存泄漏
请注意,对self的引用被指定为弱,以便您可以防止发生内存泄漏.通过将其指定为弱,它将为您提供可选的self参考.
如果不这样做,你为onNext块创建的闭包将保留对self的强引用,这就是你的UICollectionViewCell,而UICollectionViewCell又拥有我们正在讨论的闭包.