问题描述
我正在测试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相关的帖子
解决方法
我认为原因是我的背景上下文配置错误。它被设置为保留所有注册的对象。一旦我注释掉相应的代码,错误就消失了:
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
}()