跳到主要内容

Core Data

问题

Core Data 的核心概念和使用方式?常见的坑和优化?

答案

Core Data 栈

基本 CRUD

// 初始化
let container = NSPersistentContainer(name: "MyModel")
container.loadPersistentStores { _, error in
if let error { fatalError("Core Data load error: \(error)") }
}
let context = container.viewContext

// 创建
let user = User(context: context)
user.name = "Alice"
user.age = 25
try context.save()

// 查询
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "age > %d", 20)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let users = try context.fetch(request)

// 更新
users.first?.name = "Bob"
try context.save()

// 删除
context.delete(users.first!)
try context.save()

多线程

// ❌ NSManagedObjectContext 不是线程安全的
DispatchQueue.global().async {
let user = context.object(with: objectID) // 崩溃!
}

// ✅ 使用 performBackgroundTask
container.performBackgroundTask { bgContext in
let request = User.fetchRequest()
let users = try? bgContext.fetch(request)
// 在后台上下文操作
try? bgContext.save()
}

数据迁移

  • 轻量迁移:添加/删除属性、可选变非可选(有默认值)
  • 重量迁移:复杂的数据变换(需要 Mapping Model)
let description = NSPersistentStoreDescription()
description.shouldMigrateStoreAutomatically = true
description.shouldInferMappingModelAutomatically = true // 轻量迁移

常见面试问题

Q1: Core Data 和 SQLite 的关系?

答案:Core Data 不是数据库,是对象图管理框架。它可以使用 SQLite 作为底层存储(也可以用 XML、内存),提供对象关系映射(ORM)、变更追踪、撤销/重做等功能。直接用 SQLite 更适合复杂 SQL 查询。

Q2: NSFetchedResultsController 的作用?

答案:专门用于 UITableView/UICollectionView 的数据源管理。它监听 Core Data 变化,自动计算 diff 并通知 UI 进行增删改动画,类似 DiffableDataSource。

相关链接