使用NSPrivateQueueConcurrencyType保存NSManagedObjectContext [英] Saving NSManagedObjectContext with NSPrivateQueueConcurrencyType
问题描述
Im目前正在学习如何在多线程环境中使用核心数据;
Im currently learning how to use core-data in a multithreaded environment;
因此,我创建了一个小型项目,其中包含两个 NSManagedObjectContext
:主要 NSManagedObjectContext
与 NSMainQueueConcurrencyType
对于读及其子 NSManagedObjectContext 与
NSPrivateQueueConcurrencyType
用于创建/更新/删除操作。
I therefore created a small project with two NSManagedObjectContext
: A main NSManagedObjectContext
with NSMainQueueConcurrencyType
for reads and its child NSManagedObjectContext
with NSPrivateQueueConcurrencyType
for create/update/delete operations.
通常,用 NSPrivateQueueConcurrencyType $ c $保存
NSManagedObjectContext
c>应该通过 performBlock:
来实现:
It has often been said that saving an NSManagedObjectContext
with NSPrivateQueueConcurrencyType
should be done through performBlock:
like so:
[context performBlock:^
{
Book *mutableBook = [self getMutableVersionOfBook:book];
[context deleteObject:mutableBook];
[context save:nil];
}];
如果省略 performBlock:
,像这样:
Book *mutableBook = [self getMutableVersionOfBook:book];
[context deleteObject:mutableBook];
[context save:nil];
然后保存在线程上发生的保存被调用吗?如果 performBlock:
没有使用,会发生什么?
Does the save then happen on the thread the save was called on? What can happen if performBlock:
isn't used?
推荐答案
私人队列MOC只能通过 -performBlock:
或 -performBlockAndWait:
来触及。如果你触摸它任何其他方式,那么你违反了核心数据的线程边界规则,你将最终导致数据损坏。
A private queue MOC should only be touched via a -performBlock:
or -performBlockAndWait:
. If you touch it any other way then you are violating the thread boundary rule of Core Data and you will eventually cause data corruption.
在某些情况下,这将导致崩溃您的应用程序,因为违反该线程边界是一个应用程序级错误。苹果已经把这个崩溃了好几次,它可能是也可能不是一个崩溃状态现在。在我看来,应该一直处于崩溃状态。
In some situations this will cause a crash in your application because violating that thread boundary is an application level error. Apple has turned that crash off a number of times and it may or may not be a crash state right now. In my opinion, It should be a crash state all the time.
作为一般规则,我建议您使用线程限制MOCs儿童的主要MOC,而不是使用私人MOC。虽然私有MOC是好的和有用的,每个动作的结构必须在一个块,你不能访问的结果 NSManagedObject
实例,除非在那些块是限制。更好的是将一个操作分成一个队列,在队列中创建一个线程限定的MOC,然后使用更干净的代码,而不是不断地进入块(或者更糟糕的是创建巨大的不可修复的块)。
As a general rule, I recommend that you use thread confined MOCs as children of the main MOC as opposed to using private MOCs. While private MOCs are nice and useful, the structure of every action must be in a block and that you cannot access the resulting NSManagedObject
instances except in those blocks is limiting. Better to spin off an operation into a queue, create a thread confined MOC in that queue and then have cleaner code than constantly having to dive into blocks (or worse create huge un-maintanable blocks).
最后。您将 nil
传递给 -save:
。 永远不要。当你这样做时,你隐藏了一个潜在的问题。即使这只是一个例子,这是一个可怕的习惯,你应该立即打破它。即使在示例代码中,传递 NSError
并检查错误。即使你只是将结果传递给 NSLog
,你至少可以避免一个惊喜。
Finally. You are passing nil
to -save:
. Never do that. You are hiding a potential problem when you do that. Even if "it is just an example", it is a terrible habit and you should break it immediately. Even in example code, pass in a NSError
and check the error. Even if you just pass the results to NSLog
you will at least avoid a surprise.
这篇关于使用NSPrivateQueueConcurrencyType保存NSManagedObjectContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!