无法将私有队列中的上下文设置为主队列中另一个上下文的子级

Posted

技术标签:

【中文标题】无法将私有队列中的上下文设置为主队列中另一个上下文的子级【英文标题】:Unable to set a context in a private queue as child of another context in main queue 【发布时间】:2015-09-27 09:37:16 【问题描述】:

据我了解,可以在私有队列中创建一个NSManagedObjectContext,并将其父上下文设置为另一个属于主线程的NSManagedObjectContext...不是吗?

我正在尝试这样做:

NSManagedObjectContext *privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = appDelegate.managedObjectContext;
[privateContext setParentContext:mainContext]; 

但是当我运行此代码时,我在[privateContext setParentContext:mainContext] 处收到SIGABRT 错误。

我从AppDelegate检索到的mainContext在主线程中初始化,这段代码sn-p也在主线程中被调用。我会做错什么或遗漏什么?

谢谢

编辑:如果我改为这样做(AppDelegate):

NSManagedObjectContext *mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
mainContext.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
NSManagedObjectContext *privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

privateContext.parentContext = mainContext;

我没有收到任何错误...为什么会发生这种情况? AppDelegate 中提供的默认上下文有什么不能作为父上下文?

编辑 2: 我试图设置为父上下文的 AppDelegate 中的上下文是使用 AppDelegate 中默认提供的方法初始化的:

- (NSManagedObjectContext *)managedObjectContext

   // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
   if (_managedObjectContext != nil) 
       return _managedObjectContext;
   

   NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
   if (!coordinator) 
       return nil;
   
   _managedObjectContext = [[NSManagedObjectContext alloc] init];
   [_managedObjectContext setPersistentStoreCoordinator:coordinator];
   return _managedObjectContext;

【问题讨论】:

【参考方案1】:

在您的情况下,很难检测是什么引发了异常 - 信息太少。

乍一看,一切似乎都很好,但是 - 请注意按以下顺序设置您的父/子上下文:

    创建根上下文。 设置其persistentStoreCoordinator 创建子上下文 将其parentContext 设置为根上下文 继续使用 3-4 设置父/子层次结构

在您的情况下,可能会因以下原因出现异常:

    mainContextnil mainContextpersistentStoreCoordinatornil

无论如何,最快的解决方案将是由 CoreData 触发的日志异常。你可以使用NSSetUncaughtExceptionHandler

编辑 1:

为了保持一致,请尝试在AppDelegate 的初始化方法中使用NSManagedObjectContext *mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 而不是alloc/init,但这很可能无法解决问题。再次,阅读控制台中的异常消息 - 这将准确了解发生了什么问题。

【讨论】:

谢谢。我已经编辑了我的问题以提供mainContext 的初始化方法,这是我在AppDelegate 中提供的方法,我没有做任何更改。 mainContext在我尝试将其设置为父上下文时已经初始化,可能是因为初始化方法需要更改吗? @AppsDev 我已经稍微编辑了我的答案 - 请再次阅读错误消息 你是对的,这是我收到的异常消息:Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType.。谢谢

以上是关于无法将私有队列中的上下文设置为主队列中另一个上下文的子级的主要内容,如果未能解决你的问题,请参考以下文章

两个私有队列上下文之间的 mergeChangesFromContextDidSaveNotification

从新的子上下文中删除对象

CoreData:带有子主上下文的私有上下文 - FetchedResultsController 未获得更新

托管对象上下文不合并来自后台上下文的更改

如何用另一个上下文中的另一个对象替换某个上下文中的对象?

在私有/后台队列上创建 NSManagedObjectContext:怎么办?