質問

I have what I think is a simple task.

I have a method called [self getPerson] that makes a simple GET request from a web service for a Person that returns some JSON and then transforms the JSON into an NSManagedObject. checks for an existing identical Person NSManagedObject, and if none is found, saves the Person into core data. No problem.

However, If I fire off this method twice in a row, I get two Person NSMangedObjects persisted into Core Data. For example:

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

How can I ensure that only one Person object is saved in Core Data (no duplicates allowed)?

I know the issue, I just don't know how to fix it. The issue is that I need a transaction. When [self getPerson] fires the first time, the method checks for an already existing identical Person object, finds none, and saves a new Person into core data. This is correct. When I fire [self getPerson] the second time, the method checks for an already existing Person object, doesn't see one, and is then persisting another Person object. This is not correct. I would like to make it so that the second time, and third time, and fourth time, to the 1000th time, checking for an existing Person object will only occur after the managedObjectContext saveoperation is done. Right now the check for an existing object is happening so fast (before the save is done).

Do I need a serial queue? If so, should this be a dispatch_async or dispatch_sync? I've even toyed with the idea of trying to use a performSelectorWithDelay trick.

役に立ちましたか?

解決

Once you create the object it will exist in the database regardless of you calling save. So you should not create a managed object if one exists already. It's not entirely clear what your code logic is but from your description you say you transform the JSON to a managed object and then you check for an identical existing one and if none is found you save. Well when you create the managed object you have created it, so it's too late to check if an identical one exists. Saving does not create the object it just saves it to the store if it hasn't already been saved.

So first check if an person object exists with the attributes in the JSON and if not then create a managed object.

他のヒント

Well, in this case a serial queue will ensure that operations are performed in the correct manner.

From you question, maybe I'm missing something, I cannot understand if the getPerson method is responsible to both get and save data. If not, you should do it.

Anyway, if you use JSON and the person you retrieve form the server has a unique identifier, you should use that to query against Core Data and verify if it exists or not. The correct manner to do it is to implement Implementing Find-or-Create Efficiently.

A simple question. Is the any reason for calling the getPerson twice? Could you not prevent it using a flag (or a transient property)? Just simple ideas.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top