gpt4 book ai didi

ios - 多个 NSManagedObjectContexts - 防止竞争条件和死锁

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:50:34 26 4
gpt4 key购买 nike

我已经阅读了大量关于后台核心数据处理的博客,但我并没有更深入地了解如何最好地管理同时触发所有 BG 核心数据任务并以未定义的方式通知主线程 MOC时间。

我知道您应该为每个 NSThread 拥有 1 个 NSManagedObjectContext,并且通过订阅 NSManagedObjectContextDidSaveNotification 以及使用 [ context performBlock 我完成了一些不错的异步任务。

也就是说,我正在异步运行很多任务,我不能 100% 知道某些任务何时会重叠,而且我观察到竞争条件的形式是...

  • BG MOC 1 开始执行任务
  • BG MOC 2 开始执行任务
  • BG MOC 2 完成任务并发送保存通知
  • BG MOC 1 完成任务并随后删除 BG MOC 2 的更改

我的总体问题是如何解决多个 MOC 中的竞争条件?

  1. 如果正确的行为是每个线程有 1 个 MOC。我可以创建一个 NSThread ivar 并将我所有的核心数据工作放在上面吗?这样我就可以拥有一个与自身同步工作的 MOC?

  2. 我读过 NSLock 可能是避免某些代码同时从多个线程访问的解决方案..但我不知道我应该锁定什么?保存上下文方法?持久存储(似乎使多线程毫无意义)?

  3. 最后,我可以标记/编号/命名我的 MOC 吗?这样,如果我知道其他任务正在运行,我可以存储通知并按照它们实例化的顺序处理它们,以确保没有数据被覆盖?

最佳答案

  1. 建议每个线程一个 MOC。有异常(exception),但一般规则仍然适用。不要创建 NSThread 对象。只是不要。太痛苦了。而是使用 block 或 NSOperation 实例。它们更容易理解并保护您免受很多痛苦。

  2. 不要对 Core Data 使用锁。如果使用得当,Core Data 会自己加锁,如果你乱扔锁,就会导致问题。理想情况下,您应该永远需要在现代 Objective-C 中自己调用 lock。

  3. 除了具有对它们的 ivar 或属性引用之外,您不能命名 MOC。您也不需要。

使用 Core Data 进行多线程处理的最干净的方法如下:

  • 您有一个主线程/UI MOC。那是你唯一的真相来源。您的 UI 从中获取数据并写入其中。
  • 任何后台进程都是在 NSOperation 或类似结构中完成的。您在此构造内部创建一个 MOC,它是主上下文的上下文。
  • 当您保存子项时,更改将合并到父项(即 UI MOC)。
  • 设置适合您的主 MOC 的合并策略。如果您认为您需要针对不同的情况制定不同的政策,那么您应该重新设计您的行事方式。

理想情况下,每个后台进程都应该是一个数据孤岛,可以独立运行而不会与其他进程发生冲突。如果您有冲突,那么这是您需要在业务逻辑中解决的合并问题。

如果您遇到两个后台操作要访问同一 block 数据的情况,那么您应该按顺序运行它们,而不是并行运行。对相同数据的并行编辑等待发生是痛苦的,不要这样做。

您可以通过使用 NSOperationQueue 实例来控制事物是顺序的还是并行的。

遵循这些规则,您将不会出现竞争条件或死锁。

关于ios - 多个 NSManagedObjectContexts - 防止竞争条件和死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27260578/

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