我有90个名为“ItemModel”的CoreData实体,其中包含2个属性“uid”,“description”,其中每个项目都作为NSManagedObject插入:
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName: @"ItemModel" inManagedObjectContext: AFYDelegate.managedObjectContext];
第一个服务器调用将'uid'分配给上面为关键字“uid”提取的90个项目中的每一个。这里没有保存上下文。
在稍后的第二次服务器调用中,我喜欢使用indexPath更新90个项目的“description”,用于每个 NSManagedObject - 通过获取并将每个对象传递给以下方法并保存上下文:
[self updateItemToDataModel:object withData: description];
....
....
- (void)updateItemToDataModel:(NSManagedObject *) object withData:(NSString *)data
{
[object setValue:data forKey:@"description"];
NSError * error = nil;
if (![self.managedObjectContext save:&error]) {
//Handle any error with the saving of the context
NSLog(@"%@",error.localizedDescription);
}
}
以上工作在关闭模拟器并再次运行代码后更新CoreData BUT时效果很好,每个项目将有两个重复项,具有相同的'uid'和'description'。这意味着我现在有180件物品。反复关闭并运行代码会创建越来越多的项目。
我尝试删除updateItemToDataModel方法,重置模拟器,它可以正常工作90项。
如果有人可以提供帮助,我是CoreData的新手。如果我只希望更新现有项目,我的代码有什么问题?
答案 0 :(得分:1)
每次都将新对象插入MOC(托管对象上下文) - 而不是进行获取并查找要更新的对象的现有实例。
要获取现有对象,您可以像这样执行获取请求...
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"uid == %@", uidToMatch];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"ItemModel" inManagedObjectContext:managedObjectContext]];
NSError * error = nil;
NSArray * results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if ([results count]) {
// you may need to handle more than one match in your code...
// you could also set a fetch limit of 1 and guarantee you only get the first object, eg: [fetchRequest setFetchLimit:1];
}
else {
// no results
}
您可能希望将其包装在辅助函数中,以便可以重复使用它。并阅读NSFetchRequest,NSPredicate和编写谓词,以便进行更高级的获取请求。