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

每次显示视图控制器时CoreData数据重复添加至Table View问题

问题根因
  • 你声明的noteList是全局变量,生命周期和App进程一致,不会随NoteTableView页面销毁而清空。
  • firstLoad是NoteTableView的实例属性,每次重新打开页面生成新的控制器实例时,firstLoad都会重置为true,会再次触发CoreData查询,把查询到的所有笔记追加到已经有数据的全局noteList中,最终导致列表重复展示。
修复方案
  1. 把全局的noteList移动到NoteTableView类内部作为私有实例属性,脱离全局生命周期,每次打开页面都会生成新的空数组。
  2. 直接将CoreData查询结果赋值给noteList,避免循环append可能带来的冗余,也可以在查询前先清空数组进一步避免重复。
  3. 可选优化:取消firstLoad判断,每次页面出现时都重新拉取CoreData数据,保证列表展示的是最新内容(比如你在编辑页新增/删除笔记后返回列表能自动刷新)。

修改后的完整代码如下:

import UIKit
import CoreData

class NoteTableView: UITableViewController
{
    // 移动到类内部作为实例属性,每次新建页面实例都会生成新的空数组
    private var noteList = [Note]()
    
    func nonDeletedNotes() -> [Note]
    {
        return noteList.filter { $0.deletedDate == nil }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadNotesFromCoreData()
    }
    
    // 封装CoreData查询逻辑
    private func loadNotesFromCoreData() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Note")
        do {
            // 直接将查询结果赋值给noteList,不需要循环append
            if let results = try context.fetch(request) as? [Note] {
                noteList = results
            }
        } catch {
            print("Fetch Failed: \(error.localizedDescription)")
        }
    }
    
    // 新增/删除笔记后返回列表自动刷新
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        loadNotesFromCoreData()
        tableView.reloadData()
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
    UITableViewCell
    {
        let noteCell = tableView.dequeueReusableCell(withIdentifier: "noteCellID", for: indexPath) as! NoteCell
        
        let thisNote = nonDeletedNotes()[indexPath.row]
        
        noteCell.titleLabel.text = thisNote.title
        noteCell.descLabel.text = thisNote.desc1
        
        return noteCell
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return nonDeletedNotes().count
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        self.performSegue(withIdentifier: "editNote", sender: self)
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        if(segue.identifier == "editNote")
        {
            let indexPath = tableView.indexPathForSelectedRow!
            
            let noteDetail = segue.destination as? FocusWheelViewController
            
            let selectedNote = nonDeletedNotes()[indexPath.row]
            noteDetail!.selectedNote = selectedNote
            
            tableView.deselectRow(at: indexPath, animated: true)
        }
    }
  
}

内容的提问来源于stack exchange,提问作者Rem Biths Wind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 12:06:01