【发布时间】:2016-02-08 17:02:39
【问题描述】:
我是 CoreData 的新手,我正在尝试创建一个简单的应用程序。
假设我有一个函数:
func saveEntry(entry: Entry) {
let moc = NSManagedObjectContext(concurrencyType: .NSPrivateQueueConcurrencyType)
moc.parentContext = savingContext
moc.pefrormBlockAndWait {
// find if MOC has entry
// if not => create
// else => update
// saving logic here
}
}
它会引入一个问题:如果我从两个线程调用saveEntry,传递相同的条目会复制它。因此,我已将串行队列添加到我的数据库适配器并以下列方式进行:
func saveEntry(entry: Entry) {
dispatch_sync(serialDbQueue) { // (1)
let moc = NSManagedObjectContext(concurrencyType: .NSPrivateQueueConcurrencyType)
moc.parentContext = savingContext
moc.pefrormBlockAndWait { // (2)
// find if MOC has entry
// if not => create
// else => update
// saving logic here
}
}
}
它工作正常,直到我想添加另一个接口函数:
func saveEntries(entries: [Entry]) {
dispatch_sync(serialDbQueue) { // (3)
let moc = NSManagedObjectContext(concurrencyType: .NSPrivateQueueConcurrencyType)
moc.parentContext = savingContext
moc.pefrormBlockAndWait {
entries.forEach { saveEntry($0) }
}
}
}
现在我有死锁: 1 将在 serialDbQueue 上调用并等待保存完成。 2 将在私有队列中被调用并等待 3。而 3 正在等待 1。
那么处理同步访问的正确方法是什么?据我了解,由于此处描述的原因,保留一个 MOC 并对其执行保存是不安全的:http://saulmora.com/coredata/magicalrecord/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord.html
【问题讨论】:
-
您确定需要串行队列吗?如果您在该块内执行不安检查,为什么通过
performBlockAndWait将两个操作入队会给您带来问题? -
@Jonah 是的,我是。如果我用一个信号 MOC 运行所有东西 - 没关系。但正如您所见,
saveEntry会为每次调用创建一个 MOC。所以你会有并行操作 -
糟糕,我应该仔细阅读。与其使用串行队列来创建许多 moc,为什么不共享一个 moc,然后将其用作该队列?
-
你确定它是安全的吗?我看到 MagicalRecord 为每次保存创建新的上下文
标签: ios multithreading core-data magicalrecord