Swift:Core Data一对多关系下的记录删除实现需求
实现Core Data中删除Candy时自动清理关联Country的逻辑
要实现删除Candy时,若该Candy是对应Country的最后一个糖果则同时删除Country的功能,你可以按以下方式编写.onDelete的处理逻辑:
1. 编写删除处理函数
在你的View中添加专门的删除函数,负责处理Candy删除及后续Country的清理:
@Environment(\.managedObjectContext) var moc func deleteCandies(at offsets: IndexSet, from country: Country) { guard let firstOffset = offsets.first else { return } // 取出要删除的Candy对象 guard let candies = country.candies?.allObjects as? [Candy], let candyToDelete = candies[safe: firstOffset] else { return } // 计算删除后剩余的糖果数量 let remainingCount = candies.count - 1 // 删除选中的Candy moc.delete(candyToDelete) // 如果剩余数量为0,同步删除对应的Country if remainingCount == 0 { moc.delete(country) } // 保存上下文变更 do { try moc.save() } catch { print("删除操作失败: \(error.localizedDescription)") } }
2. 在List中绑定.onDelete
假设你是按国家分组展示糖果列表,将.onDelete附加到子List上,并调用上述函数:
@FetchRequest(sortDescriptors: [SortDescriptor(\Country.fullName)]) var countries: FetchedResults<Country> var body: some View { NavigationStack { List { ForEach(countries) { country in Section(header: Text(country.fullName ?? "未命名国家")) { ForEach(country.candies?.allObjects as? [Candy] ?? [], id: \.self) { candy in Text(candy.name ?? "未命名糖果") } .onDelete(perform: { offsets in deleteCandies(at: offsets, from: country) }) } } } .toolbar { EditButton() } } }
注意事项
- 修正你添加记录代码中的拼写错误:
candy1.orgin应改为candy1.origin(需与Core Data模型中Candy的关系属性名一致)。 - Core Data模型中,Country与Candy的关系设置:Country的
candies为一对多关系,Candy的origin为一对一关系,删除规则保持默认的Nullify即可。 - 代码中使用了
[safe:]下标避免越界崩溃,实现方式如下:
extension Collection { subscript(safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

