核心数据和数据完整性:读取操作与写入操作。怎么保护?

时间:2013-12-28 07:40:03

标签: ios core-data concurrency grand-central-dispatch nsoperationqueue

我认为这是一项简单的任务。

我有一个名为[self getPerson]的方法,它从一个Web服务向Person发出一个简单的GET请求,返回一些JSON,然后将JSON转换为NSManagedObject。检查现有的相同Person NSManagedObject,如果未找到,则将Person保存到核心数据中。没问题。

但是,如果我连续两次触发此方法,我会将两个Person NSMangedObjects持久保存到Core Data中。例如:

[self getPerson];
[self getPerson];  ---> yields duplicate `Person` objects saved in core data, no good.

如何确保核心数据中只保存一个Person对象(不允许重复)?

我知道这个问题,我只是不知道如何修复它。问题是我需要一个交易。当[self getPerson]第一次触发时,该方法检查已存在的相同Person对象,找不到,并将新的Person保存到核心数据中。这是对的。当我第二次触发[self getPerson]时,该方法检查已存在的Person对象,没有看到一个,然后持久保存另一个Person对象。这是不正确的。我想这样做,以便第二次,第三次,第四次,到第1000次,检查现有的Person对象只会在managedObjectContext save操作完成后发生。现在,对现有对象的检查发生得如此之快(在保存完成之前)。

我需要一个串行队列吗?如果是,那么这应该是dispatch_async还是dispatch_sync?我甚至玩弄了尝试使用performSelectorWithDelay技巧的想法。

2 个答案:

答案 0 :(得分:1)

创建对象后,无论您调用save,它都将存在于数据库中。因此,如果已存在托管对象,则不应创建托管对象。你的代码逻辑是什么并不完全清楚,但是根据你的描述,你说你将JSON转换为托管对象,然后你检查一个相同的现有对象,如果没有找到你保存。那么当您创建托管对象时,您已创建它,因此检查是否存在相同的托管对象为时已晚。如果尚未保存,则保存不会创建仅将其保存到商店的对象。

首先检查一个人物对象是否存在JSON中的属性,如果不存在则创建一个管理对象。

答案 1 :(得分:1)

好吧,在这种情况下,串行队列将确保以正确的方式执行操作。

从你的问题,也许我遗漏了一些东西,我无法理解getPerson方法是否负责获取和保存数据。如果没有,你应该这样做。

无论如何,如果您使用JSON并且您从服务器检索的人员具有唯一标识符,您应该使用它来查询Core Data并验证它是否存在。正确的方法是实施Implementing Find-or-Create Efficiently

一个简单的问题。有两次调用getPerson的原因吗?你能不能使用旗帜(或瞬态属性)阻止它吗?只是简单的想法。