当PublishSubject遇到UITableview复用机制

PublishSubject既是一个观察者,也是一个被观察者,通常用来代替delegate。如下需求:

思路很简单,点击cell里删除按钮,用PublishSubject将删除事件回调给ViewController,在ViewController里删除数据源,再更新tableView

cell里定义属性,row用定位数据源位置,这里情况特殊,数据源的indexcellrow一一对应,传入row,相当于数据源的index,到时候回调出去,就知道删除哪条数据:

var row: Int?
var deletePulish = PublishSubject<Int>()

点击删除,将传入的row回调出去:

btnDelete.rx.tap.subscribe(onNext: { [weak self] in
            if let row = self?.row {
                self?.deletePulish.onNext(row)
            }
        }).disposed(by: disposeBag)

ViewController里:

usersRelay.bind(to: tbl.rx.items(cellIdentifier: "SelectedMemberCell", cellType: SelectedMemberCell.self)) { (row, element, cell) in
            cell.lblName.text = element.userName
            cell.row = row
            cell.deletePulish.subscribe(onNext: { [weak self] row in
                self?.users.remove(at: row)
                if let users = self?.users {
                    self?.usersRelay.accept(users)
                }
            }).disposed(by: self.disposeBag)
            
            }
            .disposed(by: disposeBag)

以上都是很正常的用法。

这里隐藏了一个问题。
我点击删除孟浩然,正常。
我再点击删除杜甫,却删除了杜甫和李白两条。

经过调试,发现,cell的点击删除事件的确只发触发一次,onNext发送删除事件也只有一次。

但是ViewController里订阅事件的确执行了两次。那么问题就在于为什么发送一次,会接收两次?

只有一种可能,就是有两个对象订阅了同一个事件。

经过增加更多的数据发现规律,点一次删除一条,再点一次删除两条,第三次删除三条。。。。。。很显然,之前被删除的cell依然再接收事件。所以,问题在于,之前的cell虽然从数据源上删除了,导致不显示,但是cell本身并没有dealloc,也就是还在内存里,依然会接收事件。

ViewController里加上一句cell.deletePulish = PublishSubject<Int>(),将删除的cell里的订阅者重新赋值,就不会再接收到事件,如果deletePulish定义为可选类型,那么可以直接设为cell.deletePulish = nil

usersRelay.bind(to: tbl.rx.items(cellIdentifier: "SelectedMemberCell", cellType: SelectedMemberCell.self)) { (row, element, cell) in
            cell.lblName.text = element.userName
            cell.row = row
            cell.deletePulish.subscribe(onNext: { [weak self] row in
                cell.deletePulish = PublishSubject<Int>()
                self?.users.remove(at: row)
                if let users = self?.users {
                    self?.usersRelay.accept(users)
                }
            }).disposed(by: self.disposeBag)
            
            }
            .disposed(by: disposeBag)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 30,023评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,902评论 1 32
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 5,239评论 0 1
  • 作者:易中天 001讲究 北京人:讲究礼,"倒驴不倒架",最怕因跌份儿被人小瞧。 上海人:讲究貌。上海人"不怕天火...
    仲夏夜之梦123阅读 3,811评论 7 6
  • 细雨、校园、撑伞、漫步、顿悟,无论高配还是低配适合自己的才是最适合的人生,每个人的生活想法各不相同,或许你每天打鸡...
    凌依吟阅读 1,040评论 0 0

友情链接更多精彩内容