Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第 2 章:创建第一个 SwiftData 应用

第 2 章:创建第一个 SwiftData 应用

使用 ModelContext 进行数据的增删改查 (CRUD)

ModelContext 是 SwiftData 中管理数据操作的核心组件,负责处理对象的创建、读取、更新和删除(CRUD)。本节将详细介绍如何使用 ModelContext 实现完整的 CRUD 操作。

1. 创建对象 (insert)

// 1. 创建模型实例
let newTask = Task(title: "完成SwiftData学习", isCompleted: false)

// 2. 通过ModelContext插入对象
modelContext.insert(newTask)

// 3. 保存更改(可选,取决于是否启用自动保存)
try? modelContext.save()

关键点:

  • 直接实例化 @Model 修饰的类
  • 必须调用 insert() 方法将对象纳入管理
  • 保存操作可以是手动的,也可以通过配置自动完成

2. 读取对象 (fetch 和 @Query)

方式一:命令式查询 (fetch)

// 创建FetchDescriptor
let descriptor = FetchDescriptor<Task>(
    predicate: #Predicate { $0.isCompleted == false },
    sortBy: [SortDescriptor(\.createdAt, order: .forward)]
)

// 执行查询
let pendingTasks = try? modelContext.fetch(descriptor)

方式二:声明式查询 (@Query)

// 在SwiftUI视图中使用
struct TaskListView: View {
    @Query(sort: \.createdAt) var tasks: [Task]
    
    var body: some View {
        List(tasks) { task in
            Text(task.title)
        }
    }
}

谓词示例:

// 复杂谓词构建
#Predicate<Task> { task in
    (task.priority == .high || task.dueDate < Date()) 
    && !task.isCompleted
}

3. 更新对象

// 1. 获取对象(通过fetch或@Query)
guard let task = tasks.first else { return }

// 2. 直接修改属性(自动标记为脏数据)
task.isCompleted = true
task.completedAt = Date()

// 3. 保存更改(如果未启用自动保存)
try? modelContext.save()

特点:

  • 修改已托管对象的属性会自动触发变更跟踪
  • 不需要显式调用更新方法

4. 删除对象 (delete)

// 1. 获取要删除的对象
let taskToDelete = tasks[0]

// 2. 调用delete方法
modelContext.delete(taskToDelete)

// 3. 保存更改
try? modelContext.save()

删除规则:

  • 受 @Relationship 的删除规则约束(Cascade/Nullify/Deny)
  • 删除操作会立即从上下文中移除对象

5. 保存策略

方式配置方法特点
自动保存ModelContainer(autoSave: true)每次变更自动持久化
手动保存ModelContainer(autoSave: false)需显式调用 save()
事务保存modelContext.transaction { ... }批量操作的原子性

最佳实践:

// 批量操作使用transaction
try modelContext.transaction {
    for task in expiredTasks {
        task.status = .archived
    }
    try modelContext.save()
}

调试技巧

// 打印上下文状态
print("Has changes: \(modelContext.hasChanges)")

// 查看待处理变更
modelContext.registeredModels.forEach { object in
    print("Object: \(object), status: \(modelContext.getStatus(for: object))")
}

注意:所有持久化操作都可能抛出错误,生产代码应该实现完整的错误处理逻辑。

Last Updated:: 5/30/25, 5:21 PM