为什么不对所有Core Data操作使用privatecontext?

时间:2014-09-05 05:56:01

标签: ios objective-c multithreading core-data nsmanagedobjectcontext

在我的iPhone应用程序中,我通过Core Data登录后插入了大量数据。最初我在插入数据时显示了一个加载器,因此UI的阻塞不是问题,但现在我删除了加载器并通过将managedobjectcontext并发类型更改为NSPrivateQueueConcurrencyType来移动后台线程上的所有插入操作一些插入可以减轻UI的繁重插入工作。

我想知道如果我使用相同的上下文而不是NSMainQueueConcurrencyType用于所有操作会有什么缺点,是推荐吗?

4 个答案:

答案 0 :(得分:1)

您应该将NSPrivateQueueConcurrencyType用于所有的上下文。例如,只要您观察使用队列限制的所有规则(即必须通过队列执行提取,以及故障等),NSFetchedResultsController与私有队列上下文一起工作正常。 There is a bug with NSFetchedResultsController caching when using private queue contexts,但缓存仅涵盖有限数量的用例。

如果/当您使用Core Data中的数据更新UI元素时,您仍然必须从主队列访问UI。例如,这将访问属性以更新标签:

[[object managedObjectContext] performBlock:^{
    NSString *text  = [object someProperty];
    [NSOperationQueue mainQueue] addOperationWithBlock:^{
        [[self someLabel] setText:text];
    }];
}];

使用私有队列限制有很多好处。缺点是您必须包含上述代码 - 这远远超过在主队列上执行Core Data工作。

答案 1 :(得分:0)

只要涉及核心数据的所有操作都在此上下文中执行,就没有任何缺点。

也许差异,但并非真正的缺点是您必须异步执行所有数据操作。

顺便说一下,核心数据有自己的"背景"线程,只要你用" performBlock"执行所有操作。你没事。

What is NSManagedObjectContext's performBlock: used for?

答案 2 :(得分:0)

您应该告诉我们的真实细节是您正在运行的操作类型。

如果您没有触摸UI,则可以在其他线程中执行操作。例如,假设您从后端导入JSON数据(其中很多)。没有它,应用程序可能会冻结。

NSMainQueueConcurrencyType创建一个与主调度队列相关联的上下文,从而创建主线程。您可以使用这样的上下文将其链接到在主线程上运行所需的对象,通常是UI元素。所以,当你处理NSFetchedResultsController时,你需要它。

无论如何,我个人的建议是分析应用程序并使用线程上下文,而你却发现了瓶颈。核心数据可能变得非常复杂。所以尽可能保持简单。

答案 3 :(得分:0)

我会说缺点是你不能在NSManagedObjects之外使用-performBlock:。您必须将单个属性传输出块才能将值传递给UI元素,因为您可能无法直接从-performBlock:内部触摸UI。

此外,NSMainQueueConcurrencyType的上下文没有后台队列。 -performBlock:的作用是将块排队以便在runloop循环中执行。因此,虽然看起来代码的执行从语句继续,但是一旦块开始执行,它仍将在稍后阻塞该线程。