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

UITableView每次加载时CoreData记录出现重复单元格问题求助

UITableView重复展示CoreData记录问题解决方案

问题根因

代码里的核心问题出在两个地方:

  • 存储CoreData查询结果的数组Rec被定义为全局变量,不会随TableViewController实例销毁而清空
  • firstLoad是TableViewController的实例属性,每次重新进入页面生成新的VC实例时,firstLoad都会重置为true,触发一次新的CoreData查询,查询到的所有记录会被追加到全局的Rec数组中,导致数组里的记录每次进入页面都翻倍

修复方案

按照以下步骤修改代码即可解决问题:

  1. 将全局的Rec数组移到TableViewController类内部,作为私有属性
  2. 每次执行CoreData查询之前先清空数组,避免旧数据残留
  3. 可选优化:如果需要每次进入页面都展示最新数据,可以将查询逻辑移到viewWillAppear中,去掉firstLoad判断,保证每次进入页面都拉取最新全量数据,适配新增、修改、删除后的数据同步需求

修正后的代码示例

import UIKit
import CoreData

class TableViewController: UITableViewController {
    // 把Rec数组移到类内部,不再是全局变量
    private var Rec = [Records]()
    
    // 提前缓存未删除的记录,避免每次计算行数、取cell时重复遍历
    private var validRecords: [Records] {
        Rec.filter { $0.del == nil }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchCoreDataRecords()
    }
    
    // 每次进入页面都拉取最新数据
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        fetchCoreDataRecords()
    }
    
    // 抽取CoreData查询逻辑为独立方法
    private func fetchCoreDataRecords() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        let request = NSFetchRequest<Records>(entityName: "Records")
        
        do {
            // 查询前先清空原有数据,避免累加
            Rec.removeAll()
            // 直接指定结果类型为Records,不需要强转NSArray
            Rec = try context.fetch(request)
            tableView.reloadData()
        } catch {
            print("Fetch Failed: \(error.localizedDescription)")
        }
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! TableViewCell
        let thisrec = validRecords[indexPath.row]
        cell.idLB.text = thisrec.id
        cell.nameLB.text = thisrec.name
        cell.lastLB.text = thisrec.last
        cell.genderLB.text = thisrec.gender
        cell.ageLB.text = thisrec.age
        cell.addressLB.text = thisrec.address
        return cell
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return validRecords.count
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
        self.performSegue(withIdentifier: "editNote", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "editNote",
              let indexPath = tableView.indexPathForSelectedRow,
              let recDetail = segue.destination as? AddViewController else { return }
        recDetail.selectedCell = validRecords[indexPath.row]
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:09:03