是否有必要对 CoreData 使用合并策略并允许外部存储以避免崩溃?

发布于 2025-01-10 19:28:37 字数 2385 浏览 0 评论 0原文

我使用 CoreData + NSPersistentCloudKitContainer 来备份我的模型。我的一个 NSManagedObject 有一张存储为二进制数据的图片,并允许检查外部存储。

这是非常随机的,但有时当我调用 context.save() 时,即使我没有编辑此对象,我也会遇到合并冲突。事实上,我只是尝试创建一个新对象(与有冲突的对象类型不同),而崩溃发生在另一个对象上。

除了外部数据引用的自引用之外,所有值都是相同的:

    ERROR AppDelegate.saveContext():262 - Unresolved error Error Domain=NSCocoaErrorDomain Code=133020 "Impossible de fusionner les changements." UserInfo={conflictList=(
    "NSMergeConflict (0x600002c62f40) for NSManagedObject (0x60000158da40) with objectID '0x816659a4c358c32f <x-coredata://CEAE3B14-5782-4C18-AAE8-B05D91CFEC8A/Aquarium/p5>' with oldVersion = 56 and newVersion = 57 and old object snapshot = {\n    albums = \"<null>\";\n    aquaID = 6;\n    dateDeCreation = \"2022-01-15 18:24:00 +0000\";\n    imageData = External Data Reference: <self = 0x60000158db80 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;\n    nom = 11321;\n    volume = 60;\n} and new cached row = {\n    albums = \"<null>\";\n    aquaID = 6;\n    dateDeCreation = \"2022-01-15 18:24:00 +0000\";\n    imageData = External Data Reference: <self = 0x6000015ccf50 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;\n    nom = 11321;\n    volume = 60;\n}"
), NSExceptionOmitCallstacks=true}, ["NSExceptionOmitCallstacks": 1, "conflictList": <__NSArrayM 0x600003a25ec0>(
NSMergeConflict (0x600002c62f40) for NSManagedObject (0x60000158da40) with objectID '0x816659a4c358c32f <x-coredata://CEAE3B14-5782-4C18-AAE8-B05D91CFEC8A/Aquarium/p5>' with oldVersion = 56 and newVersion = 57 and old object snapshot = {
    albums = "<null>";
    aquaID = 6;
    dateDeCreation = "2022-01-15 18:24:00 +0000";
    imageData = External Data Reference: <self = 0x60000158db80 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;
    nom = 11321;
    volume = 60;
} and new cached row = {
    albums = "<null>";
    aquaID = 6;
    dateDeCreation = "2022-01-15 18:24:00 +0000";
    imageData = External Data Reference: <self = 0x6000015ccf50 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;
    nom = 11321;
    volume = 60;
}

我怀疑数据引用在应用程序加载和我第一次调用备份之间发生了变化。 但长度是相同的,因为这个值在用户端没有改变,所以我不明白为什么引用会改变。

我现在没有使用合并策略,它只是不保存。

我可以使用 NSMergeByPropertyObjectTrumpMergePolicy 来确保安全吗?还是应该找出引用更改的原因?

I use CoreData + NSPersistentCloudKitContainer to backup my model. One of my NSManagedObject has a picture stored as Binary Data and Allows external storage checked.

It's very random but sometimes when i call context.save() i get a merge conflict even if i don't have edit this object. In fact i just try to create a new object (different type as the one with conflicts) and the crash is on another object.

Everyting is the same value except the self reference of External Data Reference:

    ERROR AppDelegate.saveContext():262 - Unresolved error Error Domain=NSCocoaErrorDomain Code=133020 "Impossible de fusionner les changements." UserInfo={conflictList=(
    "NSMergeConflict (0x600002c62f40) for NSManagedObject (0x60000158da40) with objectID '0x816659a4c358c32f <x-coredata://CEAE3B14-5782-4C18-AAE8-B05D91CFEC8A/Aquarium/p5>' with oldVersion = 56 and newVersion = 57 and old object snapshot = {\n    albums = \"<null>\";\n    aquaID = 6;\n    dateDeCreation = \"2022-01-15 18:24:00 +0000\";\n    imageData = External Data Reference: <self = 0x60000158db80 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;\n    nom = 11321;\n    volume = 60;\n} and new cached row = {\n    albums = \"<null>\";\n    aquaID = 6;\n    dateDeCreation = \"2022-01-15 18:24:00 +0000\";\n    imageData = External Data Reference: <self = 0x6000015ccf50 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;\n    nom = 11321;\n    volume = 60;\n}"
), NSExceptionOmitCallstacks=true}, ["NSExceptionOmitCallstacks": 1, "conflictList": <__NSArrayM 0x600003a25ec0>(
NSMergeConflict (0x600002c62f40) for NSManagedObject (0x60000158da40) with objectID '0x816659a4c358c32f <x-coredata://CEAE3B14-5782-4C18-AAE8-B05D91CFEC8A/Aquarium/p5>' with oldVersion = 56 and newVersion = 57 and old object snapshot = {
    albums = "<null>";
    aquaID = 6;
    dateDeCreation = "2022-01-15 18:24:00 +0000";
    imageData = External Data Reference: <self = 0x60000158db80 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;
    nom = 11321;
    volume = 60;
} and new cached row = {
    albums = "<null>";
    aquaID = 6;
    dateDeCreation = "2022-01-15 18:24:00 +0000";
    imageData = External Data Reference: <self = 0x6000015ccf50 ; path = 1B9355A6-4101-479D-81F1-DFC106BBCD75 ; length = 1617016>;
    nom = 11321;
    volume = 60;
}

I suspect the data reference changed between the time the application loads and the first time I call the backup.
But the length is the same since this value has not been changed on the user side, so I don't understand why the reference changes.

I use no merge policy right now and it just don't save.

Can i use NSMergeByPropertyObjectTrumpMergePolicy to be safe or should i find why the reference changed ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

难忘№最初的完美 2025-01-17 19:28:37

我从未使用过 CoreData 外部数据引用,所以这是一个疯狂的猜测。
在我看来,合并冲突的出现是因为对外部文件的引用发生了变化,尽管文件的路径保持不变。
这可能是自定义合并策略的情况。您必须通过自己的代码解决合并冲突,该代码只需选择其中一个引用,因为两者都指向同一个文件。
我最近尝试针对不同的情况设置自己的自定义合并策略,但我不完全确定我做得对,请参阅我的问题、相关代码和参考文献 这里。也许您可以针对自己的情况测试类似的代码。

编辑
关于您的问题,如果您可以使用NSMergeByPropertyObjectTrumpMergePolicy:根据合并冲突,除了imageData引用之外,实体的所有属性都保持不变。因此,在尝试使用自定义合并策略之前,您应该明确尝试标准合并策略:
NSMergeByPropertyObjectTrumpMergePolicy 仅更新托管上下文中的 imageData 引用,而 NSMergeByPropertyStoreTrumpMergePolicy 仅更新来自持久存储的 imageData 引用。但由于所有其他属性都没有更改,并且两个实体中的文件路径相同,因此您同样可以尝试使用托管中的整个实体的 NSOverwriteMergePolicyNSRollbackMergePolicy上下文或持久存储,分别参见 文档。仅当由于外部引用而失败时,您才应该考虑自定义合并策略。

I have never worked with CoreData external data references, so this is a wild guess.
It seems to me that the merge conflict arises because the reference to the external file changed, although the path to the file stayed the same.
This is probably a case for a custom merge policy. You had to resolve the merge conflict by your own code that simply selects one of the references because both point anyway to the same file.
I tried recently to set up my own custom merge policy for a different situation, but I am not completely sure that I did it right, please see my question, related code and references here. Maybe you can test a similar code for your own case.

EDIT
Regarding your question, if you can use NSMergeByPropertyObjectTrumpMergePolicy: According to the merge conflict, all properties of your entity stayed the same except the imageData reference. So, before you try to use a custom merge policy, you should definitively try the standard merge policies:
NSMergeByPropertyObjectTrumpMergePolicy updates only the imageData reference from the managed context, while NSMergeByPropertyStoreTrumpMergePolicy updates only the imageData reference from the persistent store. But since all other properties did not change, and the file path in both entities is the same, you could equally well try NSOverwriteMergePolicy and NSRollbackMergePolicy that use the entire entity in the managed context or the persistent store, respectively, see the docs. Only if that fails because of the external reference, you should consider a custom merge policy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文