NSPersistentContainer并发用于保存到核心数据

NSPersistentContainer并发用于保存到核心数据,第1张

NSPersistentContainer并发用于保存到核心数据

TL:DR : TL:DR:您的问题是您同时使用viewContext
和背景环境进行编写。您只应以一种
同步方式写入核心数据。

完整说明:如果在两个
不同的上下文中同时更改了一个对象,则核心数据将不知所措。您可以设置
mergePolicy来设置应赢的变更,但这并不是一个好的
解决方案,因为您可能会丢失数据。许多专家
长期以来一直在处理该问题,其方式是让 *** 作
队列将写 *** 作排队,因此一次仅执行一次写 *** 作,而
在主线程上仅允许读 *** 作拥有另一个上下文。这样,您就永远不会遇到任何
合并冲突。(有关 此设置的详细说明,请参见https://vimeo.com/89370886
)。

进行此设置NSPersistentContainer非常容易。在您的核心数据
管理器中,创建一个NSOperationQueue

// obj c- (void)enqueueCoreDataBlock:(void (^)(NSManagedObjectContext* context))block{  void (^blockCopy)(NSManagedObjectContext*) = [block copy];  [self.persistentContainerQueue addOperation:[NSBlockOperation blockOperationWithBlock:^{    NSManagedObjectContext* context = self.persistentContainer.newBackgroundContext;    [context performBlockAndWait:^{      blockCopy(context);      [context save:NULL];  //Don't just pass NULL here, look at the error and log it to your analytics service     }];  }]];} //swiftfunc enqueue(block: @escaping (_ context: NSManagedObjectContext) -> Void) {  persistentContainerQueue.addOperation(){    let context: NSManagedObjectContext = self.persistentContainer.newBackgroundContext()      context.performAndWait{        block(context)        try? context.save() //Don't just use '?' here look at the error and log it to your analytics service      }    }}

调用时,

enqueueCoreDataBlock
该块将排队,以确保
没有合并冲突。但是,如果您写入,
viewContext
那将
破坏此设置。同样,您应该将您
创建的任何其他上下文(使用
newBackgroundContext
或使用
performBackgroundTask
)视为
只读,因为它们也将不在编写队列中。

起初我以为

NSPersistentContainer
performBackgroundTask

内部队列,并初步测试支持这一点。经过更多测试后,我
发现它也可能导致合并冲突。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4944650.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-13
下一篇2022-11-13

发表评论

登录后才能评论

评论列表(0条)

    保存