Reputation: 505
I've been working with Magical record and Core Data for a while, but still I can't figure out how to ensure object uniqueness.
Assume I have a function:
- (void) foo {
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// find if model with x = myValue exists
MyModel *model = [MyModel MR_findFirstWithPredicate:[NSPredicate predicateWithFormat:@"x = %@", myValue] inContext:localContext];
// if there is no model - create it!
if (!model) {
model = [MyModel MR_createInContext:localContext];
model.x = myValue;
// etc...
}
}];
}
Everything goes fine until foo
is called twice (or 3, 4...etc times). Now localContext
doesn't know about localContext
in other thread and uniqueness checks passes. As a result after context merge I have 2 (3,4...etc) instances with given value (instead of 1).
How can I ensure only 1 object with given value exits?
PS. —validateValue:forKey:error:
won't help, as it called BEFORE context merge (during saving object).
Upvotes: 0
Views: 135
Reputation: 80271
I guess one approach would be to check before merging and alter or delete the duplicate values. You can do this by listening to the NSManagedObjectContextWillSaveNotification
and making the changes before calling mergeChangesFromContextDidSaveNotification
.
Upvotes: 1
Reputation: 69757
The reason this doesnt work after a few loops is that the saveWithBlock method is dispatching queues under the covers for you. Because of this, each local context is a fresh new context. Each localContext is unaware of the contents in any of the others created by your loop. This means the findFirst method will return nothing every time and create a new, but duplicate copy of the model object. The way to fix this is to either,
The idea is to use the same context for all your operations so you can look up data in the context. And in some cases that data will be your newly created and unsaved data.
Upvotes: 0