如何创建/管理多个托管对象上下文?

Posted

技术标签:

【中文标题】如何创建/管理多个托管对象上下文?【英文标题】:How to create/manage multiple ManagedObjectContexts? 【发布时间】:2012-10-17 23:13:18 【问题描述】:

我有一个问题,我非常有信心从广义上知道它是什么以及如何解决它,但我不确定并且还没有找到实现的干净/最佳实践方法解决办法是。

我的问题:我正在使用 dispatch_async 在后台线程中将文件中的一些数据加载到我的核心数据模型中,它工作正常,除非我在 GUI 中执行也会影响模型然后爆炸的事情,例如:

'NSGenericException', reason: '*** Collection ... was mutated while being enumerated.'

...我认为这是由于两个线程在同一个 ManagedObjectContext 中弄乱了数据,因为我目前只使用一个。

我读过的所有文章和答案都告诉我应该为后台线程使用单独的 ManagedObjectContext,但是如何/在哪里设置它?

我目前在我的 App Delegate 中创建我的 PersistentStoreCoordinator 和(一个)ManagedObjectContext,并将 ManagedObjectContext 传递给我的(唯一)View Coordinator。它又将其传递给后台数据加载任务(这是我的一个模型类的类方法),从而导致了问题。

我应该

    把PersistentStoreCoordinator传给View Controller,这样它又可以把它传给后台任务,这样后台任务就可以创建自己的本地ManagedObjectContext了? 在 App Delegate 中创建一个 ManagedObjectContexts 池,并将它们全部传递给 View Controller,以便它可以自己使用一个并将其他的交给后台任务? 完全不同的东西?

【问题讨论】:

你能添加一些代码吗?尤其是产生异常的代码。当你说你应该在线程之间仔细管理你的 NSManagedObjectContext 对象时你是对的,但无论如何看到你的代码真的很高兴。 我还没有设法重现地创建完全相同的异常,我引用的就是一个例子。但是每当我遇到问题时,总是当我在 GUI 中做某事时会更改 ManagedObjectContext 中的某些内容,而后台任务正在加载和保存数据在同一上下文中。 【参考方案1】:

我仍然无法始终如一地重现该问题;它似乎高度依赖时间。但这是我为防止它所做的工作。

在视图控制器中:

- (void) loadNewStuff: (NSString *)stuffID

     dispatch_async(taskQueue, 
       ^(void)[MyModelClass loadNewStuff: stuffID withContext: myContext];
     );

在模型类中:

+ (void) loadNewStuff: (NSString *)stuffID withContext: (NSManagedObjectContext *)passedContext

  NSManagedObjectContext *localContext = [[NSManagedObjectContext alloc] init];
  [localContext setPersistentStoreCoordinator: passedContext.persistentStoreCoordinator];

  // load new stuff, save local context, finished


...这样可以吗,还是我忽略了会严重咬我的东西?

(我使用的是 ARC,所以我假设不显式释放本地创建的上下文是可以的?)

【讨论】:

以上是关于如何创建/管理多个托管对象上下文?的主要内容,如果未能解决你的问题,请参考以下文章

临时托管对象未正确从子上下文合并到主上下文

核心数据:创建多个托管对象,但只保存一些?

什么是托管对象上下文? [关闭]

(SWIFT 3) 创建父子托管对象上下文

核心数据 - 管理上下文

iPhone - 核心数据崩溃 - 多个托管对象上下文