當(dāng)PublishSubject遇到UITableview復(fù)用機(jī)制

PublishSubject既是一個(gè)觀察者,也是一個(gè)被觀察者,通常用來(lái)代替delegate。如下需求:

思路很簡(jiǎn)單,點(diǎn)擊cell里刪除按鈕,用PublishSubject將刪除事件回調(diào)給ViewController,在ViewController里刪除數(shù)據(jù)源,再更新tableView。

cell里定義屬性,row用定位數(shù)據(jù)源位置,這里情況特殊,數(shù)據(jù)源的indexcellrow一一對(duì)應(yīng),傳入row,相當(dāng)于數(shù)據(jù)源的index,到時(shí)候回調(diào)出去,就知道刪除哪條數(shù)據(jù):

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

點(diǎn)擊刪除,將傳入的row回調(diào)出去:

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)

以上都是很正常的用法。

這里隱藏了一個(gè)問題。
我點(diǎn)擊刪除孟浩然,正常。
我再點(diǎn)擊刪除杜甫,卻刪除了杜甫和李白兩條。

經(jīng)過(guò)調(diào)試,發(fā)現(xiàn),cell的點(diǎn)擊刪除事件的確只發(fā)觸發(fā)一次,onNext發(fā)送刪除事件也只有一次。

但是ViewController里訂閱事件的確執(zhí)行了兩次。那么問題就在于為什么發(fā)送一次,會(huì)接收兩次?

只有一種可能,就是有兩個(gè)對(duì)象訂閱了同一個(gè)事件。

經(jīng)過(guò)增加更多的數(shù)據(jù)發(fā)現(xiàn)規(guī)律,點(diǎn)一次刪除一條,再點(diǎn)一次刪除兩條,第三次刪除三條。。。。。。很顯然,之前被刪除的cell依然再接收事件。所以,問題在于,之前的cell雖然從數(shù)據(jù)源上刪除了,導(dǎo)致不顯示,但是cell本身并沒有dealloc,也就是還在內(nèi)存里,依然會(huì)接收事件。

ViewController里加上一句cell.deletePulish = PublishSubject<Int>(),將刪除的cell里的訂閱者重新賦值,就不會(huì)再接收到事件,如果deletePulish定義為可選類型,那么可以直接設(shè)為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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,209評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,626評(píng)論 1 32
  • 2017.02.22 可以練習(xí),每當(dāng)這個(gè)時(shí)候,腦袋就犯困,我這腦袋真是神奇呀,一說(shuō)讓你做事情,你就犯困,你可不要太...
    Carden閱讀 1,490評(píng)論 0 1
  • 作者:易中天 001講究 北京人:講究禮,"倒驢不倒架",最怕因跌份兒被人小瞧。 上海人:講究貌。上海人"不怕天火...
    仲夏夜之夢(mèng)123閱讀 696評(píng)論 7 6
  • 細(xì)雨、校園、撐傘、漫步、頓悟,無(wú)論高配還是低配適合自己的才是最適合的人生,每個(gè)人的生活想法各不相同,或許你每天打雞...
    凌依吟閱讀 115評(píng)論 0 0

友情鏈接更多精彩內(nèi)容