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

iOS开发:CoreData与UITableView添加任务后重复显示问题的解决

问题原因与解决方案

一、重复显示的核心原因

你的UITableView数据源配置逻辑完全错误,导致任务被重复渲染:

  1. Section数量设置错误:numberOfSections返回任务总数,意味着每有一个任务就创建一个独立的Section
  2. Row数量逻辑混乱:numberOfRowsInSection中,第0个Section返回1行,其余每个Section返回任务总数,最终总行数远大于实际任务数
  3. Cell数据绑定错误:cellForRowAt直接用indexPath.row读取viewModel.tasks数组,同一个任务会被多个Section的Row重复引用,导致重复显示

比如当有2个任务时:

  • Section数量=2
  • 第0个Section显示1行(对应tasks[0])
  • 第1个Section显示2行(对应tasks[0]、tasks[1])
  • 最终表格显示3行,其中tasks[0]重复出现

二、修复步骤

1. 修正UITableView数据源方法

修改ViewController中的UITableViewDataSource扩展,将Section数量改为1,Row数量直接返回任务总数:

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 直接返回任务总数作为当前Section的行数
        return viewModel.numberOfTasks
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "TaskTableCell", for: indexPath) as? TaskTableViewCell else {
            return UITableViewCell()
        }
        cell.configure(with: viewModel.tasks[indexPath.row])
        return cell
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        // 只需要一个Section
        return 1
    }
}

2. 删除ViewModel中无用的行数计算方法

移除TaskViewModel中的numberOfRows(by:)方法,因为已经不需要按Section区分行数:

// 删掉这个方法
func numberOfRows(by section:Int) -> Int {
    if section == 0 {
        return 1
    }
    return numberOfTasks
}

3. 修正ViewModel的任务添加逻辑,确保数据同步

修改TaskViewModel的addNewTask方法,先保存到CoreData,再重新拉取数据,避免内存数组与本地存储不一致:

func addNewTask(name: String) {
    let newItem = Item(context: CoreDataManager.shared.context)
    newItem.id = UUID()
    newItem.completed = false
    newItem.name = name
    newItem.createdAt = Date.now

    // 先保存到CoreData
    CoreDataManager.shared.addNewItem(item: newItem)
    
    // 重新拉取最新数据,更新内存中的tasks数组
    fetchAllTasks()
}

4. 可选优化:清理冗余代码

  • 移除ViewController中viewDidAppear的tasksTableView.reloadData()(如果ViewModel初始化时已经完成首次拉取,且任务添加后已通过fetchAllTasks更新数据并触发reload,该代码可省略)
  • 检查AddNewTaskViewController的savePressed方法,确保delegate?.didItemAdded()在viewModel.addNewTask之后调用,保证数据更新后再刷新表格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:38:08