Core Data 入门:从零开始掌握 iOS 数据持久化

前端里的光
2025-12-23 00:01
阅读 2210

大家好,我是掘金上常写入门教程的全栈工程师。今天这篇文章,源于我最近帮几位准备秋招的同学修改简历时,发现很多人在「项目经验」里写了“使用 Core Data 实现本地存储”,但一问原理就支支吾吾。作为过来人,我深知:不懂原理的“用过”=面试题挑战的雷区。因此,我决定写一篇真正面向零基础、手把手带你跑通 Core Data 的实战教程。

为什么选择 Core Data?

在 iOS 开发中,数据持久化(即将数据保存到设备本地)是刚需。比如你的待办事项 App 需要记住用户添加的任务,不能每次重启就清空。苹果提供了多种方案:

方案 适用场景 学习曲线
UserDefaults 少量简单配置(如用户偏好)
文件读写 图片、JSON 等原始数据 ⭐⭐
Core Data 结构化数据、关系型模型 ⭐⭐⭐
SQLite (原生) 需要极致控制或跨平台 ⭐⭐⭐⭐

Core Data 不是数据库!它是一个对象图管理和持久化框架。你操作的是 Swift 对象,它自动帮你存到 SQLite(默认)、XML 或内存中。

环境准备:创建你的第一个 Core Data 项目

我当初学的时候,第一步就卡在“要不要勾选 Use Core Data”——其实勾不勾都能用,但初学者建议勾选,Xcode 会自动生成样板代码。

  1. 打开 Xcode → Create a new Xcode project
  2. 选择 App 模板 → 点击 Next
  3. 填写 Product Name(如 MyTodoApp
  4. 关键一步:勾选 ✅ Use Core Data
  5. 选择保存位置,点击 Create

此时你会看到:

  • 项目中多了一个 .xcdatamodeld 文件(如 MyTodoApp.xcdatamodeld
  • AppDelegate.swift 中多了 persistentContainer 相关代码

核心概念三要素:Entity, Attribute, Context

别被术语吓到,用生活例子理解:

  • Entity(实体) = 数据表(如 “任务表”)
  • Attribute(属性) = 表的字段(如 “标题”、“是否完成”)
  • NSManagedObjectContext(上下文) = 操作数据的“工作区”,所有增删改查都在这里进行

步骤 1:定义数据模型

  1. 点击 MyTodoApp.xcdatamodeld
  2. 点击左下角 + 号 → Add Entity
  3. 将新 Entity 命名为 Task
  4. 在 Attributes 区域添加两个属性:
    • title → Type: String
    • isCompleted → Type: Boolean

💡 新手注意:Entity 名首字母大写,Attribute 名小写,这是约定。

步骤 2:生成 Swift 类(Model)

  1. 选中 Task Entity
  2. 右侧 Inspector 面板 → Codegen 选择 Class Definition
  3. Command + B 编译项目

Xcode 会自动生成 Task+CoreDataClass.swiftTask+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 语句
  • 自动处理关系(如一对多)、懒加载内存管理
  • 支持撤销/重做批量操作等高级功能

学习建议与资源推荐

下一步学什么?

  1. 关系建模:比如“用户”有多个“任务”
  2. 后台保存:避免阻塞 UI 线程
  3. 数据迁移:App 升级时修改数据模型
  4. 性能优化:批量插入、分页加载

推荐资源

资源类型 名称
官方文档 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

最热最新
暂无评论
前端里的光Lv.1
0
影响力
0
文章
0
粉丝