首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于rx.tap for UIButton in UICollectionViewCell - RxSwift 3的问题

关于rx.tap for UIButton in UICollectionViewCell - RxSwift 3的问题
EN

Stack Overflow用户
提问于 2017-04-04 12:09:49
回答 2查看 19K关注 0票数 9

我为1 UIButton订阅了2次:

  1. 第一次订阅,用于每次单击更新UI。
  2. 第二次订阅,用于在累积单击后每1秒更新Web服务上的值。

代码:

代码语言:javascript
运行
复制
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调用将被释放,而不是更新。

我尝试过的:

  1. addDisposableTo(vc?.rx_disposableBag)添加到父ViewController DisposableBag中。 问题是,订阅的累积和每次点击updateWS()调用多次,这是订阅的每一个卷轴,从来没有处理。
  2. 我尝试将disposableBag重新初始化从prepareForReuse()中删除。 问题是,对按钮的订阅重复和累积,每次点击都会调用许多webservice调用。

问题:如何才能将debounce订阅调用到末尾,并且不重复多次订阅(在addDisposableTo viewController包的情况下)?

EN

回答 2

Stack Overflow用户

发布于 2017-04-11 15:33:54

由于prepareButton()总是在集合视图的(cellForItemAt indexPath: IndexPath)中调用,所以您可以尝试这样做:

代码语言:javascript
运行
复制
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()实现。

票数 11
EN

Stack Overflow用户

发布于 2017-04-04 16:20:02

addDisposableTo(vc?.rx_disposableBag)添加到父ViewController DisposableBag中。 问题是,订阅是累积起来的,每次单击updateWS()都会多次调用它,这些订阅在每个滚动卷上都被订阅,并且从未被释放。

您的self.updateOnWS()可能会被多次调用,因为您订阅了按钮的点击。

代码语言:javascript
运行
复制
    btn_increase.rx.tap
        .debounce(1.0, scheduler: MainScheduler.instance)
        .subscribe(){ event in self.updateOnWS() }
        .addDisposableTo(rxBag)

如您所见,您可以使用subscribe()方法订阅所有事件。这意味着所有Rx事件(onNextonErroronCompletedonSubscribedonDisposed)都会触发self.updateOnWS()。您可以通过打印event对象来检查是否是这种情况,以查看触发了什么事件。

仅在onNext上订阅

一个可能的解决方法可能是只订阅onNext操作。

代码语言:javascript
运行
复制
    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所导致的内存泄漏的内容。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43206862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档