You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:48:33