将多上下文CoreData应用于基于NSOperationQueue的应用程序

时间:2013-11-13 08:10:18

标签: ios uitableview core-data concurrency nsmanagedobjectcontext

我仍然在使用我的RSS阅读器,虽然它最终实现了不错的功能,但在iPad 3上,UI响应性似乎非常糟糕。

为了改善我的应用程序,我在互联网上检查了很多来源并且遇到this interesting gem Marcus Zarra的方法(有一个父母MOC致力于在背景中保存到PSC)诱惑了我。

example provided by Matthew Morey看起来很漂亮,但只考虑了一个操作:UITableView中条目的大量加载。

我尝试将此解决方案应用到我的应用中,但这显然是一团糟。 我有一个MasterViewController,在启动时会创建一系列DBOperation对象,并将其发送到一个序列(最多1个并发)NSOperationQueue。

我的每个UIViewControllers还执行单独保存的单独CoreData操作(将帖子标记为编辑,将类别标记为打开或关闭等)。

所以,我的问题是:

  • 我应该如何(简而言之)在我的应用中实现多上下文的CoreData?
  • 哪个控制器应该添加哪个观察者来重新加载各自的UITableView?
  • 哪个控制器或委托应执行观察NSManagedObjectContextDidSaveNotification / mergechange操作?

我对所有这一切感到困惑,马库斯·扎拉的出色书对我的帮助太小了,也许是因为我从一开始就采取了错误的方式......

提前感谢您的帮助

2 个答案:

答案 0 :(得分:2)

  • 每个线程基本上需要1个NSManagedObjectContext。

  • 为主线程创建一个上下文,将由所有viewcontrollers使用。在视图控制器中,您可以使用NSFetchedResultsController,因为它们的数据发生更改时会收到通知,这会自动触发tableview更新。

  • 每个后台线程都需要拥有自己的托管对象上下文。必须在该后台线程中创建此上下文,例如:

    NSManagedObjectContext *managedObjectConctext = [[[NSManagedObjectContext alloc] init] autorelease];
    [managedObjectConctext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
    managedObjectConctext.undoManager = nil;
    managedObjectConctext.mergePolicy = NSOverwriteMergePolicy;
    
    return managedObjectConctext;
    
  • 因此,后台线程只应使用此上下文来获取/更新托管对象。因此,最重要的规则是不访问其他线程中的托管对象。 (或者在一个上下文中获取并在另一个上下文中进行更新...)

  • 保存通知应该在主线程的上下文中实现,因为后台上下文中的每个更新都将与主上下文合并,这将触发视图控制器更新其内容(在适当的时候)。

答案 1 :(得分:1)

Marcus S. Zarra实际上以他出色的"Core Data 2nd Edition" book回答了我的问题(如果你今年只购买一本Core-Data书籍,那就是那本书吧!),他在那里用了一个很好的章节来实现并发。

我碰巧忽略了孩子/父母关系如何与MOC合作。

我刚刚了解到MOC与父MOC一起声明但没有PSC会在调用save方法时将其更改“推”到其父级。

如果我们的主线程MOC本身是私人“作家”MOC的孩子,使用他自己的私人队列,那么我们可以级联save,这将在我们的主要MOC中非常快(不涉及光盘),然后在私人作家MOC的后台延迟,从而保持GUI响应。

我还了解到,当MOC使用私人队列时,他只能在performBlockperformBlockAndWait区块内访问。

非常感谢你的帮助,Leijonien,你得到了赞成!