2025-01-19 17:01:30
,某些文章具有时效性,若有错误或已失效,请在下方留言。删除 SwiftData 对象需要两个步骤:首先在你的模型上下文上调用 delete()
方法,并传入你想要删除的对象;然后保存更改,可以通过显式调用 save()
,或者如果启用了自动保存,则等待自动保存触发。
因此,对于单个对象,你可以这样编写代码:
struct ContentView: View {
@Environment(\.modelContext) private var context
var body: some View {
List(students) { student in
Text(student.name)
.swipeActions {
Button("Delete", systemImage: "trash", role: .destructive) {
context.delete(student)
}
}
}
}
}
如果你正在处理一个对象集合,你需要使用类似于以下的 for
循环:
func delete(_ indexSet: IndexSet) {
for i in indexSet {
let student = students[i]
modelContext.delete(student)
}
}
如果你想删除特定模型类型的所有对象,可以使用 delete(model:)
重载,如下所示:
do {
try modelContext.delete(model: School.self)
} catch {
print("Failed to delete all schools.")
}
如果你只想删除对象的一个子集,可以使用带有谓词的 delete(model:)
,如下所示:
try modelContext.delete(
model: School.self,
where: #Predicate { school in
school.students.isEmpty
}
)
调用 delete()
会将对象标记为待删除,但实际删除需要调用 save()
。在此之前,对象会存储在 deletedModelsArray
中,如果删除被回滚,对象会恢复到实时数据中。如果禁用自动保存且未手动调用 save()
,删除将自动回滚。
在删除有关系的对象时,SwiftData 会处理这些关系。默认使用.nullify
删除规则,或者根据设置的.cascade
规则进行级联删除,例如,删除学校会删除所有学生,删除学生又会删除他们的考试结果。
清空数据库
如果你想删除并销毁所有 SwiftData
对象—即特定容器中每个模型的每个实例—你可能会认为应该调用ModelContainer
的 deleteAllData()
。然而,从iOS 17.0开始,这个方法并没有用处:调用成功后,SwiftData 只与底层数据存储断开连接,数据并未改变,下次创建相同容器时数据会恢复。
再次强调,deleteAllData()
并不会按你期望的方式工作。
相反,你需要对每种模型类型调用模型上下文的 delete(model:)
方法,且不提供限制删除对象的谓词。例如,对于 Country
和 City
模型,可以这样操作:
do {
try modelContext.delete(model: Country.self)
try modelContext.delete(model: City.self)
} catch {
print("清除所有 Country 和 City 数据失败。")
}
需要注意的是,这并不意味着完全重置模型容器:所有的表定义和其他数据仍将保留,唯一变化的是数据将变为空。以下示例确保删除和保存操作得到了正确执行:
let result = try? context.fetch(FetchDescriptor<Country>())
if let oldResult = result {
for data in oldResult {
context.delete(data)
}
try? context.save()
}
根据时间删除示例
删除超过一天前创建的数据
let calendar = Calendar.current
var dateAgo: Date = calendar.date(
byAdding: .day, value: -1, to: Date()
)!
try? context.delete(model: School.self, where: #Predicate { data in
data.createAt < dateAgo
})
超过一个月前创建的时间
var dateAgo: Date = calendar.date(
byAdding: .day, value: -7, to: Date()
)!
超过一个月前创建的时间
var dateAgo: Date = calendar.date(
byAdding: .month, value: -1, to: Date()
)!
超过一季度前创建的时间
var dateAgo: Date = calendar.date(
byAdding: .month, value: -3, to: Date()
)!
超过半年前创建的时间
var dateAgo: Date = calendar.date(
byAdding: .month, value: -6, to: Date()
)!
超过一年前创建的时间
var dateAgo: Date = calendar.date(
byAdding: .year, value: -1, to: Date()
)!
暂无评论内容