SwiftData中如何持久化跟踪选中子项并规避删除报错?
解决SwiftData跟踪选中项及删除警告问题
1. 修复删除警告:给currentThingToDo配置关系规则
你看到的警告是因为currentThingToDo作为指向ThingToDo的关联属性,没有设置删除传播规则。当被关联的ThingToDo被删除时,CoreData无法自动处理这个引用,只能手动修复并抛出提示。
修改Person类,给currentThingToDo添加@Relationship注解并设置.nullify删除规则(删除关联对象时自动将该属性置为nil):
@Model class Person { var name: String @Relationship(deleteRule: .cascade, inverse: \ThingToDo.person) var thingsToDo = [ThingToDo]() // 添加关系注解与删除规则 @Relationship(deleteRule: .nullify) var currentThingToDo: ThingToDo? }
2. 简化删除代码
你当前的删除逻辑里,手动从thingsToDo数组移除元素是多余的——SwiftData的@Relationship数组会自动同步上下文的删除操作,无需手动修改数组。简化后的删除函数如下:
private func deleteTheThingToDo(_ indexSet: IndexSet) { withAnimation { indexSet.forEach { index in let thingToDelete = person.thingsToDo[index] modelContext.delete(thingToDelete) } do { try modelContext.save() } catch { print("保存上下文出错:\(error)") } } }
修改后,若删除的是currentThingToDo指向的对象,该属性会自动被置为nil,不会再出现警告。
3. 替代方案:通过ID跟踪选中项(可选)
如果不想用直接的对象关联,也可以在Person类中存储选中项的persistentModelID,这种方式更轻量化,也能避免关系同步的潜在问题:
@Model class Person { var name: String @Relationship(deleteRule: .cascade, inverse: \ThingToDo.person) var thingsToDo = [ThingToDo]() // 存储选中项的持久化ID var selectedThingID: PersistentIdentifier? // 计算属性,快速获取当前选中对象 var currentThingToDo: ThingToDo? { guard let id = selectedThingID else { return nil } return modelContext.model(for: id) as? ThingToDo } }
选中项时赋值:
person.selectedThingID = selectedThingToDo.persistentModelID
这种方式下,删除选中项后currentThingToDo会自动返回nil,不会产生关系警告,但需要手动通过ID查找对象,适合对关系同步有顾虑的场景。
内容的提问来源于stack exchange,提问作者RRR
相关产品推荐
相关产品推荐

