使用NSPrivateQueueConcurrencyType保存NSManagedObjectContext [英] Saving NSManagedObjectContext with NSPrivateQueueConcurrencyType

查看:370
本文介绍了使用NSPrivateQueueConcurrencyType保存NSManagedObjectContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆