我正在尝试使用新的核心数据API NSPersistentContainer,并且给人的印象是内部排队机制将阻止写入事务同时进行评估,如以下堆栈溢出答案中 所述,用于保存到核心数据的NSPersistentContainer并发
许多专家长期以来一直在处理该问题(甚至在NSPersistentContainer做到这一点之前),其方式是让操作队列将写入排队,因此一次只能进行一次写入,并具有另一个上下文在主线程上仅用于读取。这样,您就永远不会遇到任何合并冲突。(有关此设置的详细说明,请参阅https://vimeo.com/89370886,这是NSPersistentContainer内部执行的操作)。当您调用performBackgroundTask时,persistentContainer使该块进入内部串行队列。这样可以确保不存在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()
}
}
Run Code Online (Sandbox Code Playgroud)
我在github上发布了一个示例项目来演示该问题:https …