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
  • 第 4 章:数据操作与管理

第 4 章:数据操作与管理

更新对象:直接修改 @Model 实例的属性

在 SwiftData 中,更新持久化对象是一个直观且高效的过程。由于 SwiftData 采用声明式设计,对 @Model 对象的修改会自动被框架跟踪,并在适当的时候同步到持久化存储中。

基本更新流程

  1. 获取目标对象
    通过 @Query 或 ModelContext.fetch() 获取需要修改的 @Model 实例:

    let task = try context.fetch(FetchDescriptor<Task>()).first
    
  2. 直接修改属性
    像操作普通 Swift 对象一样直接赋值:

    task?.title = "更新后的任务标题"
    task?.isCompleted = true
    
  3. 自动变更跟踪
    SwiftData 会自动检测到这些变更,无需手动调用类似 objectWillChange 的方法。

关键特性说明

自动脏标记(Dirty Tracking)

  • 所有 @Model 对象会自动记录属性变更
  • 修改后的对象会被标记为 "dirty",等待后续保存

批量更新模式

// 批量更新多个对象
tasks.forEach { task in
    task.priority = .high
}

与 SwiftUI 的深度集成

在视图层直接绑定可编辑状态:

struct TaskEditView: View {
    @Bindable var task: Task // @Bindable 支持双向绑定
    
    var body: some View {
        TextField("Title", text: $task.title)
        Toggle("已完成", isOn: $task.isCompleted)
    }
}

保存策略

虽然修改会立即反映在内存中,但需要显式保存到持久化存储:

do {
    try context.save() // 显式保存变更
} catch {
    print("保存失败: \(error)")
}

性能优化建议

  1. 批量操作
    集中修改多个属性后再调用一次 save()

  2. 避免冗余保存
    利用 SwiftUI 的生命周期(如 .onDisappear)自动保存

  3. 后台线程处理
    对于大量更新,使用 ModelActor 在后台执行:

    @ModelActor 
    func batchUpdate() async {
        let tasks = try? context.fetch(...)
        tasks?.forEach { $0.status = .archived }
        try? context.save()
    }
    

常见问题解决

问题:修改后 UI 未更新
✅ 确保使用 @Bindable 或 @ObservedObject
✅ 检查是否在主线程修改属性

问题:保存时冲突
✅ 实现 mergePolicy 处理版本冲突
✅ 考虑使用 NSMergeByPropertyObjectTrumpMergePolicy

代码示例

// 完整更新示例
func updateTask(id: UUID, newTitle: String) {
    let predicate = #Predicate<Task> { $0.id == id }
    let descriptor = FetchDescriptor(predicate: predicate)
    
    if let task = try? context.fetch(descriptor).first {
        task.title = newTitle
        task.lastModified = Date.now
        
        do {
            try context.save()
        } catch {
            context.rollback()
            print("更新失败: \(error)")
        }
    }
}

提示:SwiftData 的更新操作是符合 ACID 特性的,确保数据一致性。对于复杂事务,建议使用 ModelContext.perform 块来封装操作。

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