上下文模式?为什么Core Data需要它?

时间:2011-06-24 15:17:54

标签: objective-c multithreading ios core-data nsmanagedobjectcontext

我仍然是Core Data的新手,并且我试图理解为什么它需要传递一个NSManagedObjectContext。据我了解,需要传递上下文,以便多个线程不会影响相同的上下文,但我也认为这种模式有时被视为反模式,如here所述。

核心数据理论上是否可以以线程安全的方式实现,以避免使用此模式?其他ORM(例如Ruby的ActiveRecord)如何避免这种模式?例如,CoreData无法实现per-NSManagedObject保存方法,例如在此extension中。这个轻量级框架不处理多线程,但NSManagedObjects不能使用某种内部GCD队列来支持它,它们没有暴露内部上下文?

很抱歉,如果我遗漏了任何重大内容。

2 个答案:

答案 0 :(得分:5)

NSManagedObjectContext是应用程序对象图的内存容器,就像持久存储(XML,SQLite等)通常代表对象图的磁盘容器一样。

这种方法有一些优点:

  1. 故障可以应用于一组对象,或者在CoreData的情况下应用于整个对象图
  2. 这是一个方便的抽象,可以强制应用程序批量处理它的I / O.
  3. 它提供单点联系,有效地在整个对象图上执行操作(NSFetchRequests等)
  4. 撤消可以应用于对象图,而不仅仅是单个对象。
  5. 记住CoreData不是ORM框架也很重要,它是一个对象持久性框架。 CoreData的主要职责是使访问以磁盘上的持久格式存储的数据更加高效。但是,它不会尝试模拟关系数据库的功能。

    关于并发性,在即将发布的Mac OSX中引入了新的并发模型。您可以在developer.apple.com上阅读更多相关信息。

    在摘要中,为托管对象上下文选择的并发模型更多地与单个应用程序的细节相关,而不是上下文模式本身。通常不应在线程之间共享NSManagedObjectContext的实例。

    每个线程都需要它自己的NSAutoReleasePool实例,每个线程也应该拥有自己的MOC。这样,当线程完成执行时,它可以将其更改提交到磁盘上的存储,然后释放上下文,释放在线程上处理的对象所消耗的所有内存。

    这比允许单个上下文在给定应用程序的生命周期中持续消耗系统资源更有效。当然,这可以通过在上下文中调用-reset来完成,这将导致上下文使用的所有NSManagedObject都被重新转换为错误。

答案 1 :(得分:0)

每个线程需要一个NSManagedObjectContext。因此,您可以在主线程上填充UI,并且对于每个后台线程,您需要更长时间的操作。如果您希望将结果与其他线程合并,那么您可以订阅一个通知,以便快速将更改的内容合并到主MOC中。