gpt4 book ai didi

ios - 使用 performBackgroundTask 将多个核心数据插入分派(dispatch)到 NSPersistentContainer 时合并冲突

转载 作者:搜寻专家 更新时间:2023-10-30 23:09:05 25 4
gpt4 key购买 nike

我正在试验新的核心数据 API NSPersistentContainer,我的印象是内部排队机制会阻止写入事务并发评估,详见堆栈溢出答案 NSPersistentContainer concurrency for saving to core data

The way that a lot of pros have been dealing with the problem for a long time (even before NSPersistentContainer did it) was to have an operation queue to queue the writes so there is only one write going on at a time, and have another context on the main thread only for reads. This way you never get any merge conflicts. (see https://vimeo.com/89370886 for a great explanation on this setup which is now what NSPersistentContainer does internally). When you call performBackgroundTask the persistentContainer enqueues that block into an internal serial queue. This ensure that there are no mergeConflicts.

但是,如果我在每次迭代中使用 performBackgroundTask 在紧密循环中插入共享关系目标的多个实体,我在保存上下文时会收到 NSMergeConflict 错误:

            let bundlePath = Bundle.main.resourceURL!

let directoryEnumerator = FileManager.default.enumerator(at: bundlePath, includingPropertiesForKeys: [URLResourceKey.isDirectoryKey, URLResourceKey.nameKey])
while let url = directoryEnumerator?.nextObject() as? URL {

if url.pathExtension == "jpeg" {
let imageData = try! Data(contentsOf: url)

DataManager.persistentContainer.performBackgroundTask { (context) in

// context.mergePolicy = NSMergePolicy.overwrite

let new = Photo(context: context)
new.name = url.lastPathComponent
new.data = imageData as NSData

let corresponding = try! context.existingObject(with: DataManager.rootFolder.objectID) as! Folder
new.parent = corresponding

try! context.save()
}
}

我在github上发布了一个示例项目来演示这个问题: https://github.com/MaximeBoulat/NSPersistentContainer_Merge_Conflict

崩溃似乎正在发生,因为多个实体同时为同一个父级设置它们的“父级”关系,这导致父级的“子级”关系在并发更新中不同步。

即使我将传入上下文的 .automaticallyMergesChangesFromParent 属性设置为 true,也会发生这种情况。我可以通过定义传入上下文的合并策略来防止崩溃,但这不是一个可接受的解决方案。

有什么方法可以配置 NSPersistentContainer 以正确序列化使用 performBackgroundTask API 分派(dispatch)的更新。还是我遗漏了什么导致这些更新相互冲突?或者 Apple 是否为 NSPersistentContainer 堆栈提供了预期,即在评估传递到 performBackgroundTask 的逻辑时遇到的任何冲突都应该是致命的,或者被忽略?

最佳答案

我写了你引用的答案。我错了。我已经更新了。

我发现 NSPersistentContainerperformBackgroundTask 没有功能性的内部队列,它会导致合并冲突。当我最初测试它时,它似乎是这样,但我和你一样发现可能存在冲突。幸运的是,通过创建自己的队列来解决这个问题并不难。我知道 Apple 发布如此破烂的东西似乎很奇怪,但事实确实如此。

很抱歉发布了错误的信息。

关于ios - 使用 performBackgroundTask 将多个核心数据插入分派(dispatch)到 NSPersistentContainer 时合并冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43104179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com