You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TableView重复单元格问题:点赞触发后新增单元格而非更新点赞数

问题分析与修复方案

你猜的没错!问题确实出在数据源的更新逻辑上——当Firebase触发.modified事件时,你直接把更新后的motivationDailyModel追加到了motivationThoughts数组里,这就导致数组里多了一条重复数据,TableView自然会渲染出一个全新的单元格。

要解决这个问题,我们需要找到数组中对应ID的旧模型,用新数据替换它,而不是新增。具体修复如下:

核心修复思路

  • 利用每个模型的RealMotivationID(Firebase文档的唯一标识)定位数组中需要更新的元素
  • 替换旧模型,而非追加新模型
  • 保留主线程更新UI的逻辑,确保界面刷新安全

修改后的完整代码

func loaddailymotivation() {
    FirebaseReferece(.MotivationDAILY).addSnapshotListener { querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error fetching snapshots: \(error!)")
            return
        }
        
        snapshot.documentChanges.forEach { diff in
            // 提取数据并初始化模型,避免重复代码
            let data = diff.document.data()
            let dailyMotivationID = data["objectID"] as! String
            let dailymotivationTitle = data["Motivation title"] as! String
            let dailyMotivationScripture = data["daily motivation scripture"] as! String
            let dailyMotivationNumberOfLikes = data["Number of likes in daily motivation post"]as! Int
            let updatedModel = motivationDailyModel(RealMotivationID: dailyMotivationID,
                                                    RealmotivationTitle: dailymotivationTitle,
                                                    RealmotivationScrip: dailyMotivationScripture,
                                                    RealmotivationNumberOfLikes: dailyMotivationNumberOfLikes)
            
            switch diff.type {
            case .added:
                // 可选:添加存在性检查,防止意外重复触发added事件导致数据重复
                let modelExists = self.motivationThoughts.contains { $0.RealMotivationID == dailyMotivationID }
                if !modelExists {
                    self.motivationThoughts.append(updatedModel)
                }
            case .modified:
                // 找到对应ID的模型索引,替换旧数据
                if let targetIndex = self.motivationThoughts.firstIndex(where: { $0.RealMotivationID == dailyMotivationID }) {
                    self.motivationThoughts[targetIndex] = updatedModel
                }
            case .removed:
                // 可选:如果业务支持删除帖子,在这里移除对应模型
                if let targetIndex = self.motivationThoughts.firstIndex(where: { $0.RealMotivationID == dailyMotivationID }) {
                    self.motivationThoughts.remove(at: targetIndex)
                }
            }
        }
        
        DispatchQueue.main.async {
            self.tableview.reloadData()
        }
    }
}

额外说明

  • 我把重复的模型初始化代码提取出来,减少冗余让逻辑更清晰
  • 新增了.removed事件的处理逻辑,如果你的业务需要支持删除帖子可以直接使用
  • .added事件的存在性检查是额外的保险措施,防止Firebase监听器异常重复触发导致数组数据重复

这样修改后,当点赞数更新时,数组里对应的模型会被直接替换,TableView重新加载后就会更新原有单元格的点赞数,不会再创建新的单元格了。

内容的提问来源于stack exchange,提问作者Rayisooo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:22:42