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

求助:重启App后Core Data无法保留数据的原因及解决

嘿,我一眼就看到了你代码里的关键问题,这就是导致重启App后数据“丢失”的原因!咱们来一步步解决:

1. 最致命的错误:实体名称不匹配

你在保存数据的时候用的是Task实体:

let entity = NSEntityDescription.entity(forEntityName: "Task", in: managedContext)!

但获取数据的时候却请求了Person实体:

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Person")

这就导致重启App后,你的代码根本找不到之前保存的Task数据,自然看起来像是丢失了。

2. 其他需要修正的细节

  • 全局的task数组最好明确类型,避免隐式类型带来的意外问题;
  • 保存多个属性时,应该在同一个NSManagedObject实例上设置,而不是多次调用save(否则会生成多个独立的实体对象);
  • App启动时要主动调用CoreData.fetch(),才能加载之前保存的数据到UI中。

修正后的完整代码

CoreData.swift

import Foundation
import UIKit
import CoreData

// 明确全局数组的类型
var task: [NSManagedObject] = []

class CoreData {
    // 优化save方法,支持同时传入多个属性
    static func save(category: String, taskName: String?) {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        
        // 安全获取Task实体,避免崩溃
        guard let entity = NSEntityDescription.entity(forEntityName: "Task", in: managedContext) else {
            print("Core Data模型中未找到Task实体")
            return
        }
        
        let taskObj = NSManagedObject(entity: entity, insertInto: managedContext)
        taskObj.setValue(category, forKey: "category")
        if let name = taskName {
            taskObj.setValue(name, forKey: "task_name")
        }
        
        do {
            try managedContext.save()
            task.append(taskObj)
            print("数据保存成功")
        } catch let error as NSError {
            print("无法保存数据:\(error), \(error.userInfo)")
        }
    }
    
    // 修正fetch方法的实体名称为Task
    static func fetch() {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Task")
        
        do {
            task = try managedContext.fetch(fetchRequest)
            print("成功加载\(task.count)条已保存数据")
        } catch let error as NSError {
            print("无法获取数据:\(error), \(error.userInfo)")
        }
    }
}

ViewController.swift

class ViewController: UIViewController {
    @IBOutlet weak var tfCat: UITextField!
    @IBOutlet weak var tfTask: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // App启动时加载已保存的数据
        CoreData.fetch()
        // 这里可以添加UI刷新逻辑,比如表格视图reloadData()
    }
    
    func saveDetail() {
        let category = tfCat.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        let taskName = tfTask.text?.trimmingCharacters(in: .whitespacesAndNewlines)
        
        // 简单校验分类不为空
        guard !category.isEmpty else {
            print("分类名称不能为空")
            return
        }
        
        CoreData.save(category: category, taskName: taskName)
        // 保存后刷新UI
        // tableView.reloadData()
    }

    @IBAction func btnCreate(_ sender: Any) {
        self.saveDetail()
    }
}

最后要确认的点

请检查你的Core Data模型文件(.xcdatamodeld):

  • 实体名称确实是Task(大小写完全一致);
  • 实体的属性名category和task_name和代码里的key完全匹配(Core Data的属性名是大小写敏感的)。

这样修改后,重启App就能正常加载之前保存的数据了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:58:14