gpt4 book ai didi

iOS:同步对 CoreData 的访问

转载 作者:行者123 更新时间:2023-11-29 01:15:07 24 4
gpt4 key购买 nike

我是 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
}
}
}

它工作得很好,直到我想添加另一个接口(interface)函数:

func saveEntries(entries: [Entry]) {
dispatch_sync(serialDbQueue) { // (3)
let moc = NSManagedObjectContext(concurrencyType: .NSPrivateQueueConcurrencyType)
moc.parentContext = savingContext

moc.pefrormBlockAndWait {
entries.forEach { saveEntry($0) }
}
}
}

现在我遇到了死锁:将在serialDbQueue上调用1并等待保存完成。 2 将在专用队列上被调用并等待 3。3 正在等待 1。

那么处理同步访问的正确方法是什么?据我了解,保留一个 MOC 并对其执行保存是不安全的,原因如下:http://saulmora.com/coredata/magicalrecord/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord.html

最佳答案

我会尝试使用单个 NSManagedObjectContext 作为控制机制来实现它。每个上下文维护一个串行操作队列,因此多个线程可以调用 performBlock:performBlockAndWait: 而没有任何并发​​访问的危险(尽管您必须小心上下文数据在 block 入队的时间以及它最终执行的时间)。只要上下文中的所有工作都在正确的队列上完成(通过 performBlock),就不会存在将多个线程的工作排队的内在危险。

当然需要考虑一些复杂的因素,如果不了解您的应用,我无法提供真正的建议。

  • 哪个对象将负责创建此上下文以及如何将它提供给需要它的每个对象?
  • 使用共享上下文,很难知道在该上下文上的工作何时“完成”(它的操作队列为空)是否代表您的应用程序中的一个有意义的状态。
  • 如果您想在发生错误时放弃未保存的修改,则在共享上下文中更难放弃更改(您需要实际还原这些更改,而不是简单地丢弃上下文而不保存)。<

关于iOS:同步对 CoreData 的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35275155/

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