多线程 – iOS 9核心数据线程

iOS 9中的核心数据存在问题我在iOS 8中没有.

我有一个包含多个NSManagedObjectContext对象的环境.父上下文是并发类型NSMainQueueConcurrencyType,并且所有视图控制器都有自己的子上下文对象.我使用这种系统的原因是因为我希望有更多独立的上下文,只有在我决定应该完成时才合并它们.子上下文在私有队列上,因为它在后台线程上工作,然后在主线程上的父上下文将更改传播到DB并在主线程上执行它所需的操作.

所有这些工作都很好,直到iOS 9.我得到的行为相当奇怪.例如,当我添加类型A的新对象时,它会传播到存储.如果我在同一个vc上添加另一个类型为A的对象,使用相同的上下文但是从另一个按钮,则不会调用performBlockAndWait:moc并且我的应用程序在控制台中没有任何消息时冻结.如果尝试使用第一个按钮,它每次都会通过.

- (BOOL)saveChildContext:(NSManagedObjectContext*)childContext
{
[childContext performBlockAndWait:^{
    NSError* error;

    [childContext save:&error];

    [_managedObjectContext performBlock:^{
        NSError* parentError;
        [_managedObjectContext save:&parentError];
    }];
}];

}

如果我调用performBlock :,两种情况下一切都很好.所以我发现这可能是由于一些错误的线程造成的.另一方面,使用相同类型的对象相同的线程,但另一个按钮,一切都很顺利.这让我感到困惑,并且怀疑它与线程有什么关系.

我的问题:

1)是在反向线程上拥有子上下文对象的正确方法,并且具有保存到DB并在主线程上返回GUI的上下文,或者是否有更好的约定,如果有,为什么?

2)代码在iOS 8上运行.但是,它似乎不会进入performBlockAndWait:方法.为什么这个块有时不会被执行?是否有可能其他一些线程阻塞?如何判断是否是这种情况?

最佳答案 在我看来,你的设置并不理想.为什么在视图控制器中使用背景上下文?视图控制器是UI接口,应使用主上下文.

在您的代码示例中,您在后台线程中使用主要上下文,我认为这是有问题的.

这是一个运行良好的标准设置(包括iOS9).

rootContext (Private Queue)   --> saves to persistent store --> has child
mainContext (Main Queue)      --> used in UI                --> has children
workerContext (Private Queue) --> create at will to do background stuff

通过这种方式,保存到持久性存储始终是最后的,并且始终在后台进行.这非常安全且性能良好.

我使用ad hoc工作者上下文,例如从服务器检索后保存在后台队列上的东西,或处理可以取消的对象编辑(你只是扔掉上下文).保存工作者上下文将更新UI(因为更改被“推送”到主上下文,主上下文可以通过例如NSFetchedResultsControllerDelegate方法或NSNotificationCenter进行响应).

点赞