CoreData:使用 NSCKImportOperation 删除传播预取失败

Posted

技术标签:

【中文标题】CoreData:使用 NSCKImportOperation 删除传播预取失败【英文标题】:CoreData: Delete propagation prefetching failed using NSCKImportOperation 【发布时间】:2020-11-01 11:30:11 【问题描述】:

我正在测试 CoreData+CloudKit,即我正在使用 NSPersistentCloudKitContainer 来处理与 iCloud 的所有通信。 当我启动应用程序时,CoreData 会自动与 iCloud 同步,即(除其他外)插入或更新的记录被导入到 CoreData。没有记录被删除。 我的测试在模拟器上运行。

我的第一次尝试是只使用viewContext。要将远程更改合并到此上下文中,我设置了

viewContext.automaticallyMergesChangesFromParent = true

此外,我正在使用历史跟踪as suggested by Apple,但历史处理也使用viewContext,而不是新的背景上下文。 这工作正常,除了使用 viewContext 会阻止 UI 的预期。

因此,我的第二次尝试是通过背景上下文处理历史记录(正如 Apple 所建议的那样)。 现在重复记录以下错误(显然是永远):

CoreData:删除传播预取失败,异常: 获取请求的实体 0x6000017a2050 'NSCKImportOperation' 似乎 来自与此上下文不同的 NSManagedObjectModel

即使在我删除了仪表板中的所有 iCloud 记录并从模拟器中删除了应用程序之后,也会记录此错误。 我只使用了一个 NSManagedObjectModel 与关系,但所有关系都有删除规则“无操作”。

为了检查这个错误的原因,我设置了一个运行时断点,应用程序停止并显示以下堆栈跟踪:

我应该提到错误消失,如果我设置了

viewContext.automaticallyMergesChangesFromParent = false

但我当然需要自动合并才能正确操作。

我的问题是: 这真的是一个错误吗? (日志说“它似乎……”)。 可能是什么原因造成的,如何避免?

PS:CoreData预取相关的帖子还有很多,但是没有找到CoreData+CloudKit相关的帖子

【问题讨论】:

【参考方案1】:

我认为原因是我的背景上下文配置错误。它被设置为保留所有注册的对象。一旦我注释掉相应的代码,错误就消失了:

private (set) lazy var backgroundContext: NSManagedObjectContext! = 
    let context = persistentContainer.newBackgroundContext()
    context.name = "backgroundContext"
    
    // For possible merge policies see <https://developer.apple.com/documentation/coredata/nsmergepolicy/merge_policies>
    context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    
    /*
    CAUTION: DO NOT ENABLE THE FOLLOWING STATEMENT:
    context.retainsRegisteredObjects = true
    If enabled, the following error is reported indefinitely:
    ShopEasy[20204:2672392] [error] CoreData: Delete propagation prefetching failed with exception: 
    The fetch request's entity 0x600003764630 'NSCKImportOperation' appears to be from a different NSManagedObjectModel than this context's
    */
            
    // Pin the context to the current generation token and set it to keep itself up to date with local changes.
    context.automaticallyMergesChangesFromParent = true
    context.performAndWait 
        do 
            try context.setQueryGenerationFrom(.current)
         catch 
            fatalError("###\(#function): Failed to pin viewContext to the current generation: \(error)")
        
    
    return context
()

【讨论】:

以上是关于CoreData:使用 NSCKImportOperation 删除传播预取失败的主要内容,如果未能解决你的问题,请参考以下文章

Coredata 单表简单使用

CoreData:Ubiquity:使用本地存储:1 永远不会变成 0

CoreData 使用 NSBatchInsertRequest

CoreData:使用 IN 基于谓词/数组进行排序

使用 NSFetchedResultsController 更新 CoreData 对象

CoreData简单使用