【发布时间】:2018-12-11 14:58:47
【问题描述】:
我一直在谷歌、stackoverflow 和互联网上徘徊,试图了解如何处理核心数据和处理并发性。
假设我们有 2 张桌子,活动和房间。 一个活动可以有 1 个以上的房间。
FunctionA - 添加事件
FunctionB - 添加房间
FunctionC - SearchRoom -> 返回 RoomEntity 或 nil
我的问题,我不断收到这些错误
Error Domain=NSCocoaErrorDomain Code=133020 "Could not merge changes." UserInfo={conflictList=(
"NSMergeConflict (0x10a507160) for NSManagedObject (0x1092f00c0) with objectID '0xd000000000040000 <x-coredata://A34C65BD-F9F0-4CCC-A9FB-1B1F5E48C70E/Rooms/p1>' with oldVersion = 116 and newVersion = 124 and old object snapshot = {\n location = Lisboa;\n name = \"\\U00cdndico LX\";\n} and new cached row = {\n location = Lisboa;\n name = \"\\U00cdndico LX\";\n}"
注意房间的信息是相等的
我的方法如下。
1-我调用了一次webservice(它带来了一个json,其中包含3种事件的数据)这3个都具有相同的json结构并共享由参数传递的相同的managedObjectContext
2- 我创建了一个托管对象
var managedObjectContext: NSManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext = persistentContainer.viewContext
managedObjectContext.parent?.mergePolicy = NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType
3-
managedObjectContext.perform(
{
do
{
try self.deleteAllEventsFromDb()
FunctionA(eventList, managedObjectContext) -> save
FunctionA(eventList2, managedObjectContext) -> save
FunctionA(eventList3, managedObjectContext) -> save
self.DatabaseDispatchGroup.enter()
try managedObjectContext.save()
self.DatabaseDispatchGroup.leave()
completion(Result.Success(true))
}
catch let error as NSError
{
print("Could not save. \(error), \(error.userInfo)")
completion(Result.Success(false))
}
})
4- 对于每个事件,我执行相同的 FunctionA 以在数据库 (managedObjectContext.insert(eventEntity)) 中创建和保存数据。这将适用于几个表,但我们只考虑事件和房间(FunctionB)。
5- 函数A 包含函数B。函数 B 搜索现有 Room(FunctionC->返回实体?)如果不存在(nil),则创建实体(我应该保存在这里吗?)
6- 如果 Room 存在,获取实体并尝试更新数据
不确定它是否有任何区别,但是当我保存时,我会在 dispatchGroup 之间进行这些保存
DatabaseDispatchGroup.enter()
try managedObjectContext.save()
DatabaseDispatchGroup.leave()
我使用的是用于所有数据库请求的静态 managedObjectContext,但现在我决定为每个访问数据库的函数创建一个 objectContext。
我确实为所有请求保留相同的 persistentContainer 和相同的 DispatchGroup
private override init() {
persistentContainer = NSPersistentContainer(name: "DataModel")
persistentContainer.loadPersistentStores() { (description, error) in
if let error = error {
fatalError("Failed to load Core Data stack: \(error)")
}
}
}
在我看来,我的问题是我将更改存储在内存中,并且总是对初始数据进行更新,这意味着当我执行 save() 时,上下文不会为下一次操作更新数据?
我应该如何/何时执行保存功能?
谢谢
【问题讨论】:
-
您可以在核心数据中使用父子模式进行并发developmentnow.com/2015/04/28/…
-
我的第一种方法是使用静态 MOC,但它不起作用,我仍然遇到并发问题。我认为这是因为我将 DispatchGroup 与 .perform 混合在一起(我认为它们的目标相同)。因此,如果我将静态 MOC 与 .perform 一起使用,它应该可以正常工作吗?
标签: swift xcode core-data concurrency