我一直在使用魔法记录和核心数据一段时间,但我仍然无法弄清楚如何确保对象的唯一性。
假设我有一个功能:
- (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...
}
}];
}
一切顺利,直到foo
被调用两次(或3,4,等等)。现在localContext
在其他线程和唯一性检查过程中不知道localContext
。因此,在上下文合并之后,我有2个(3,4 ...等)实例具有给定值(而不是1)。
如何确保只有一个具有给定值的对象退出?
PS 即可。 —validateValue:forKey:error:
无效,因为它称为 BEFORE 上下文合并(在保存对象期间)。
答案 0 :(得分:1)
我猜一种方法是在合并之前检查并更改或删除重复值。您可以通过在调用NSManagedObjectContextWillSaveNotification
之前收听mergeChangesFromContextDidSaveNotification
并进行更改来执行此操作。
答案 1 :(得分:0)
在几个循环之后这不起作用的原因是saveWithBlock方法为你调度队列。因此,每个本地环境都是一个全新的背景。每个localContext都不知道您的循环创建的任何其他内容。这意味着findFirst方法每次都不返回任何内容,并创建模型对象的新副本。解决这个问题的方法是,
我们的想法是为您的所有操作使用相同的上下文,以便您可以在上下文中查找数据。在某些情况下,数据将是您新创建和未保存的数据。