我为1 UIButton订阅了2次:
代码:
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()
}
}
问题:
由于释放发生在prepareForReuse()
上,如果我多次单击该按钮并立即滚动,则webservice调用将被释放,而不是更新。
我尝试过的:
addDisposableTo(vc?.rx_disposableBag)
添加到父ViewController DisposableBag中。
问题是,订阅的累积和每次点击updateWS()
调用多次,这是订阅的每一个卷轴,从来没有处理。prepareForReuse()
中删除。
问题是,对按钮的订阅重复和累积,每次点击都会调用许多webservice调用。问题:如何才能将debounce
订阅调用到末尾,并且不重复多次订阅(在addDisposableTo
viewController包的情况下)?
发布于 2017-04-11 15:33:54
由于prepareButton()
总是在集合视图的(cellForItemAt indexPath: IndexPath)中调用,所以您可以尝试这样做:
func prepareButton() {
self.rxBag = nil
let rxBag = DisposeBag()
// This for subscribing for every click for displaying purpose
btn_increase.rx.tap
.subscribe(onNext: { [weak self] _ 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(onNext: { [weak self] _ in
self?.updateOnWS()
})
.addDisposableTo(rxBag)
self.rxBag = rxBag
}
删除prepareForReuse()
实现。
发布于 2017-04-04 16:20:02
将
addDisposableTo(vc?.rx_disposableBag)
添加到父ViewController DisposableBag中。 问题是,订阅是累积起来的,每次单击updateWS()都会多次调用它,这些订阅在每个滚动卷上都被订阅,并且从未被释放。
您的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()
。您可以通过打印event
对象来检查是否是这种情况,以查看触发了什么事件。
仅在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
的引用被指定为弱引用,这样就可以防止内存泄漏的发生。通过指定它是弱的,它将为您提供一个可选的自我引用。
如果不这样做,您为onNext
块创建的闭包将保留对self
(即您的UICollectionViewCell
)的强烈引用,而后者又拥有我们正在讨论的闭包。
这最终会导致内存不足的崩溃。请参阅我在您的问题的评论上发布的参考资料,以了解更多关于错误引用self所导致的内存泄漏的内容。
https://stackoverflow.com/questions/43206862
复制相似问题