RxSwift 使用小技巧

1、debounce

过滤掉高频产生的元素,例如定位改变时刷新接口,短时间多次调会造成服务器压力过大,可以使用debounce限流,下面例子10s刷新一次


debounce.png
NotificationCenter.default.rx.notification(Notification.Name(rawValue: "kLocationUpdated"))
      .debounce(10, scheduler: MainScheduler.instance)
      .subscribe(onNext: {[weak self] (notification) in
        guard let strongSelf = self else { return }
        // 刷新数据
}).disposed(by: disposeBag)

2、takeUntil

忽略掉在第二个 Observable 产生事件后发出的那部分元素,例如cell进行复用时,忽略之前的订阅

takeUntil.png

先扩展cell的复用序列

extension Reactive where Base: UITableViewCell {
  public var prepareForReuse: RxSwift.Observable<Void> {
        var prepareForReuseKey: Int8 = 0
        if let prepareForReuseOB = objc_getAssociatedObject(base, &prepareForReuseKey) as? Observable<Void> {
            return prepareForReuseOB
        }
     //将cell复用和deinit转换为序列
        let prepareForReuseOB = Observable.of(
            sentMessage(#selector(Base.prepareForReuse)).map { _ in }
            , deallocated)
            .merge()
        objc_setAssociatedObject(base, &prepareForReuseKey, prepareForReuseOB, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)

        return prepareForReuseOB
    }
}

takeUntil当cell复用或者销毁cell button 回来复用之前的订阅

cell.button.rx.tap.takeUntil(cell.rx.prepareForReuse)
    .subscribe(onNext: { () in
        print("点击了 \(indexPath)")
    })

3、cell重复订阅问题

除了刚刚上面的takeUntil方法,也可以对cell扩展一个专用DisposeBag

extension Reactive where Base: UITableViewCell {
  public var reuseBag: DisposeBag {
        MainScheduler.ensureExecutingOnScheduler()
        var prepareForReuseBag: Int8 = 0
        if let bag = objc_getAssociatedObject(base, &prepareForReuseBag) as? DisposeBag {
            return bag
        }
        
        let bag = DisposeBag()
        objc_setAssociatedObject(base, &prepareForReuseBag, bag, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        
        _ = sentMessage(#selector(Base.prepareForReuse))
            .subscribe(onNext: { [weak base] _ in
                let newBag = DisposeBag()
                guard let base = base else {return}
                objc_setAssociatedObject(base, &prepareForReuseBag, newBag, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            })
        return bag
    }
}

cell使用扩展的reuseBag 防止重复订阅

cell.button.rx.tap
    .subscribe(onNext: { () in
        print("点击了 \(indexPath)")
    })
    .disposed(by: cell.rx.reuseBag)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 RxSwift入坑解读-你所需要知道的各种概念 沸沸腾关注 2016.11.27 19:11*字...
    枫叶1234阅读 2,921评论 0 2
  • RxSwift 使用详解系列 Rx Rx是ReactiveX的缩写,简单来说就是基于异步事件序列的响应式编程。Rx...
    内心强大的Jim阅读 950评论 0 0
  • 首先,何为RxSwift? RxSwift是ReactiveX的Swift版本,一个响应式变成框架。传送门 开始之...
    cocoawork丶阅读 531评论 0 3
  • //PublishSubject -> 会发送订阅者从订阅之后的事件序列 PublishSubjectlet se...
    andrewJN阅读 1,673评论 0 3
  • 最近在学习RxSwift相关的内容,在这里记录一些基本的知识点,以便今后查阅。 Observable 在RxSwi...
    L_Zephyr阅读 1,871评论 1 4

友情链接更多精彩内容