iOS 9核心数据线程

时间:2015-09-23 16:03:03

标签: multithreading core-data ios9

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

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

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

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

    [childContext save:&error];

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

}

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

我的问题:

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

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

2 个答案:

答案 0 :(得分:1)

在我看来,您的设置并不理想。为什么在视图控制器中使用背景上下文?视图控制器是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进行响应。

答案 1 :(得分:0)

我想通了(谢谢Mundi)我的一个类初始化了自己的NSManagedObjectContext对象来获取一些数据。后来我将相关的对象从不同的上下文中获取。不知何故,我可以这样做,虽然它不可能,甚至必须避免尝试以这种方式连接对象。始终使用相同的上下文来处理在它们之间有关系的对象。

所以,我最终使用childContext = someObjet.managedObjectContext;来获取对正确上下文的引用,而不是返回新上下文的childContext = [dbClient createChildContext];