如何避免@FetchRequest临时显示已删除的Core Data对象?
Core Data删除对象后SwiftUI视图仍显示已删除条目的问题解决
问题原因
SwiftUI的@FetchRequest默认不会自动过滤标记为isDeleted的对象,而UIKit的NSFetchedResultsController内部会自动排除这类条目。当你在后台上下文删除对象并保存后,视图上下文通过automaticallyMergesChangesFromParent同步了删除状态(将对象标记为isDeleted = true),但这些对象依然会留在FetchedResults集合中,直到视图上下文执行完整刷新或重新查询才会被移除,最终导致UI出现无效的空数据行。
解决方法
1. 给@FetchRequest添加过滤谓词(推荐方案)
直接在@FetchRequest中加入排除已删除对象的条件,从根源上避免已删除对象进入查询结果:
struct RootView: View { // 添加谓词过滤未被删除的对象,可根据需求补充排序规则 @FetchRequest( sortDescriptors: [], predicate: NSPredicate(format: "isDeleted == NO") ) var blahs: FetchedResults<Blah> var body: some View { List { // 头部内容 ForEach(blahs) { blah in SubView(blah) } } } }
添加该谓词后,blahs集合只会包含未被标记删除的对象,后台删除操作同步后,已删除对象会直接从FetchedResults中移除,不会出现在UI中。
2. 手动刷新视图上下文(补充方案)
若需保留原始查询逻辑,可在后台删除完成后手动触发视图上下文刷新,强制移除已删除对象:
persistentContainer.bgContext.perform { persistentContainer.bgContext.delete(someObject) do { try persistentContainer.bgContext.save() // 回到主线程刷新视图上下文 DispatchQueue.main.async { persistentContainer.viewContext.refreshAllObjects() } } catch { // 处理保存错误 } }
此方法需要手动管理刷新时机,性能开销略高于谓词过滤,仅作为备选方案。
3. 确认上下文合并策略(可选)
虽然你的PersistentContainer配置正确,但可确保后台上下文的合并策略符合预期:
bgContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
这一步通常不是问题核心,但能确保上下文变更同步的正确性。
内容的提问来源于stack exchange,提问作者jsadler
相关产品推荐
相关产品推荐

