2013-07-09 2 views
0

я 90 CoreData сущности под названием «ItemModel» с 2-мя атрибутов «UID», «описание», где каждый из элемента вставляется как NSManagedObject:CoreData, обновляющая NSManagedObject более одного раза, сохраняет несколько копий?

NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName: @"ItemModel" inManagedObjectContext: AFYDelegate.managedObjectContext]; 

Первый вызов сервер присваивает «UID» для каждый из 90 предметов, выбранных выше для ключевого «uid». Контекст здесь не сохраняется.

На более поздний втором вызове сервера, я хотел бы обновить «описание» для 90 элементов, для каждый из NSManagedObject с помощью indexPath - путем выборки и передачи каждого объекта следующего способа и сохранения контекста:

[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, но после закрытия симулятора и повторного запуска кода для каждого элемента будут два дубликата с теми же «uid» и «description». Это означает, что сейчас у меня есть 180 предметов. Повторное закрытие и запуск кода создает все больше и больше элементов.

Я попытался удалить метод updateItemToDataModel, сбросив симулятор, и он отлично работает с 90 элементами.

Я новичок в CoreData, если кто-то может помочь. Что случилось с моим кодом, если я только хотел обновить существующие элементы?

+0

Как вы извлекаете свой «объект»? У вас есть этот код? – Jamie

+1

Извлечение объекта по indexPath в UICollectionView и NSFetchedResultsController - NSIndexPath * indexPath = [[self.collectionView indexPathsForSelectedItems] lastObject]; NSManagedObject * object = [[self fetchedResultsController] objectAtIndexPath: indexPath]; – chongsj

ответ

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 и напишите предикаты, чтобы делать запросы выбора fancier.

+0

Удивительный! Спасибо Николаю! Просто для уточнения результатов NSArray возвращаются объекты класса NSManagedObject, и я просто делаю setValue? И когда я должен правильно сохранить self.managedObjectContext? - это в ViewDidUnload из RootViewController или AppDelegate applicationWillTerminate? – chongsj

+1

Возвращает массив всех управляемых объектов, которые соответствуют указанному имени сущности и указанному предикату. В этом случае ваш объект (ы) ItemModel. Решать, когда сохранять ваши данные, зависит от вас. Выполнение сохранения может быть дорогостоящим, поэтому вы хотите подождать, пока ваш пользователь сделает изменения (например: при отмене интерфейса редактирования). Вероятно, вы не хотите ждать, пока ваше приложение будет закрыто для сохранения - потому что если он сработает, вы потеряете все свои данные. (И, кстати, никогда не полагайтесь на viewDidUnload или applicationWillTerminate для вызова - нет гарантии, что они когда-либо будут вызваны.) –

+0

Еще раз спасибо за отличный совет. – chongsj

Смежные вопросы