Core Data 入门:从零开始掌握 iOS 数据持久化
大家好,我是掘金上常写入门教程的全栈工程师。今天这篇文章,源于我最近帮几位准备秋招的同学修改简历时,发现很多人在「项目经验」里写了“使用 Core Data 实现本地存储”,但一问原理就支支吾吾。作为过来人,我深知:不懂原理的“用过”=面试题挑战的雷区。因此,我决定写一篇真正面向零基础、手把手带你跑通 Core Data 的实战教程。
为什么选择 Core Data?
在 iOS 开发中,数据持久化(即将数据保存到设备本地)是刚需。比如你的待办事项 App 需要记住用户添加的任务,不能每次重启就清空。苹果提供了多种方案:
| 方案 | 适用场景 | 学习曲线 |
|---|---|---|
| UserDefaults | 少量简单配置(如用户偏好) | ⭐ |
| 文件读写 | 图片、JSON 等原始数据 | ⭐⭐ |
| Core Data | 结构化数据、关系型模型 | ⭐⭐⭐ |
| SQLite (原生) | 需要极致控制或跨平台 | ⭐⭐⭐⭐ |
Core Data 不是数据库!它是一个对象图管理和持久化框架。你操作的是 Swift 对象,它自动帮你存到 SQLite(默认)、XML 或内存中。
环境准备:创建你的第一个 Core Data 项目
我当初学的时候,第一步就卡在“要不要勾选 Use Core Data”——其实勾不勾都能用,但初学者建议勾选,Xcode 会自动生成样板代码。
- 打开 Xcode → Create a new Xcode project
- 选择 App 模板 → 点击 Next
- 填写 Product Name(如
MyTodoApp) - 关键一步:勾选 ✅ Use Core Data
- 选择保存位置,点击 Create
此时你会看到:
- 项目中多了一个
.xcdatamodeld文件(如MyTodoApp.xcdatamodeld) AppDelegate.swift中多了persistentContainer相关代码
核心概念三要素:Entity, Attribute, Context
别被术语吓到,用生活例子理解:
- Entity(实体) = 数据表(如 “任务表”)
- Attribute(属性) = 表的字段(如 “标题”、“是否完成”)
- NSManagedObjectContext(上下文) = 操作数据的“工作区”,所有增删改查都在这里进行
步骤 1:定义数据模型
- 点击
MyTodoApp.xcdatamodeld - 点击左下角 + 号 → Add Entity
- 将新 Entity 命名为
Task - 在 Attributes 区域添加两个属性:
title→ Type: StringisCompleted→ Type: Boolean
💡 新手注意:Entity 名首字母大写,Attribute 名小写,这是约定。
步骤 2:生成 Swift 类(Model)
- 选中
TaskEntity - 右侧 Inspector 面板 → Codegen 选择 Class Definition
- Command + B 编译项目
Xcode 会自动生成 Task+CoreDataClass.swift 和 Task+CoreDataProperties.swift。打开后者,你会看到:
extension Task {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Task> {
return NSFetchRequest<Task>(entityName: "Task")
}
@NSManaged public var title: String?
@NSManaged public var isCompleted: Bool
}
这就是你的数据模型类!可以直接在代码中使用。
实战:实现一个待办事项列表
我们将在 ContentView(假设你用 SwiftUI)中展示和添加任务。
1. 获取上下文(Context)
在 SceneDelegate.swift 或 @main 入口处,Xcode 已生成:
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
在 SwiftUI 中,通常通过 Environment 传递:
// 在 App 结构体中
@StateObject private var persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
2. 保存一条任务
在需要添加任务的地方(如按钮点击事件):
func addTask(in context: NSManagedObjectContext) {
let newTask = Task(context: context)
newTask.title = "学习 Core Data"
newTask.isCompleted = false
do {
try context.save()
print("✅ 任务已保存")
} catch {
print("❌ 保存失败: \(error)")
}
}
3. 查询所有任务
使用 @FetchRequest(SwiftUI 专用)自动监听数据变化:
struct ContentView: View {
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Task.title, ascending: true)],
animation: .default
) var tasks: FetchedResults<Task>
var body: some View {
List(tasks, id: \.self) { task in
Text(task.title ?? "无标题")
}
}
}
🔍 注意:
task.title是 Optional(因为数据库允许 NULL),所以用??提供默认值。
4. 删除任务
func deleteTask(_ task: Task, in context: NSManagedObjectContext) {
context.delete(task)
do {
try context.save()
} catch {
print("删除失败")
}
}
新手常见问题解答
Q1:为什么保存后数据没更新 UI?
原因:未在正确的 NSManagedObjectContext 中操作。
解决方案:确保增删改查都使用同一个 context(通常是 viewContext)。在多线程场景需用 perform,但初学者先专注主线程。
Q2:编译时报错 “Could not merge models”?
原因:修改了 .xcdatamodeld 后未处理版本迁移。
避坑指南:开发阶段可直接删除 App 重装;上线后需配置轻量级迁移(本篇暂不展开)。
Q3:Core Data 和直接用 SQLite 有什么区别?
- Core Data 抽象了 SQL,你操作对象而非 SQL 语句
- 自动处理关系(如一对多)、懒加载、内存管理
- 支持撤销/重做、批量操作等高级功能
学习建议与资源推荐
下一步学什么?
- 关系建模:比如“用户”有多个“任务”
- 后台保存:避免阻塞 UI 线程
- 数据迁移:App 升级时修改数据模型
- 性能优化:批量插入、分页加载
推荐资源
| 资源类型 | 名称 |
|---|---|
| 官方文档 | Core Data Programming Guide |
| 视频教程 | WWDC 2019: Mastering Core Data with CloudKit |
| 开源项目 | GitHub 搜索 “Core Data Todo” 查看完整实现 |
| 面试题库 | 在 LeetCode 或牛客网搜索 “iOS Core Data 面试题” |
写在最后:技术分享的价值
我在掘金写教程的初衷,就是希望减少大家踩我当年踩过的坑。简历上写“熟悉 Core Data”前,请确保你能解释清楚 Managed Object Context 的作用——这往往是面试官的第一道题。
记住:数据持久化不是魔法,而是你对数据生命周期的掌控。从今天这个待办事项开始,你已经迈出了第一步。动手敲一遍代码,比看十篇文章都有效!
本文完整代码已上传至 GitHub(链接见掘金原文评论区),欢迎 Star & Fork。如有疑问,欢迎在评论区留言讨论!

评论 0