第 4 章:数据操作与管理
删除对象:使用 ModelContext.delete()
基本删除操作
在 SwiftData 中,删除对象是通过 ModelContext 的 delete() 方法实现的。该方法接受一个符合 @Model 协议的实例作为参数:
// 获取要删除的对象(示例)
let taskToDelete = try context.fetch(FetchDescriptor<Task>()).first
// 删除对象
if let taskToDelete {
context.delete(taskToDelete)
}
删除的级联行为
当删除一个对象时,其关联对象的行为取决于定义的 @Relationship 删除规则:
- Cascade:同时删除关联对象(默认值)
- Nullify:将关联对象的引用设为 nil
- Deny:如果有关联对象存在,则阻止删除
@Model
class Project {
@Relationship(deleteRule: .cascade)
var tasks: [Task] = []
}
批量删除
可以通过组合 FetchDescriptor 和循环实现批量删除:
let overdueTasks = try context.fetch(
FetchDescriptor<Task>(
predicate: #Predicate { $0.dueDate < Date.now }
)
)
for task in overdueTasks {
context.delete(task)
}
删除的注意事项
- 立即生效:删除操作会立即从上下文中移除对象,但需要调用
save()才会持久化 - 内存管理:被删除对象的引用会变为无效状态,继续访问可能导致崩溃
- 撤销支持:在调用
save()前,可以通过context.undoManager撤销删除操作
删除后保存
do {
try context.save() // 持久化删除操作
} catch {
print("删除保存失败:\(error.localizedDescription)")
// 处理错误:可能是违反删除规则(如 Deny 规则阻止)
}
调试技巧
- 在删除前检查对象状态:
print(context.isDeleted(object: task)) // 检查是否已被标记删除
- 使用
NSLog或print输出删除操作的调试信息 - 在 Xcode 的 Core Data 调试面板中观察变更(SwiftData 底层使用 Core Data)
最佳实践
- 始终在主线程执行删除操作(SwiftData 要求线程限制)
- 对批量删除操作考虑性能影响,可能需要分批处理
- 在 UI 中删除时提供确认机制,特别是重要数据
- 考虑实现"软删除"模式(通过标记属性而非物理删除)
