NSMergeConflict для NSManagedObject

#core-data #nsmanagedobject

#основные данные #nsmanagedobject

Вопрос:

Я выполняю несколько запросов асинхронно, и каждый ответ возвращает xml. Мне нужно извлечь xml (я использую TBXML для его анализа) и сохранить его в Core Data. Это невозможно сделать в основном потоке, потому что пользовательский интерфейс будет слишком медленным. Я делаю следующее для каждого ответа xml:

 dispatch_queue_t request_queue = dispatch_queue_create("com.queue.name", NULL);
dispatch_async(request_queue, ^{
      AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
      NSManagedObjectContext *newMOC = [[NSManagedObjectContext alloc] init];
      [newMOC setPersistentStoreCoordinator:[appDelegate persistentStoreCoordinator]];
      newMOC setUndoManager:nil];

      NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
      [notify addObserver:self 
            selector:@selector(mergeChanges:) 
            name:NSManagedObjectContextDidSaveNotification 
            object:newMOC];
      [self traverseElement:tbxml.rootXMLElement inMOC:newMOC];
      [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:newMOC];
      [newMOC release];
});
dispatch_release(request_queue);

- (void)mergeChanges:(NSNotification*)notification 
{
    AppDelegate *theDelegate = [[UIApplication sharedApplication] delegate];
    [[theDelegate managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification 
    waitUntilDone:YES];
  

}

В методе traverseElement я анализирую xml и вставляю данные в Core Data. При выполнении этого я получаю много конфликтов слияния, подобных приведенному ниже. Есть идеи, почему или какие-либо подсказки для отладки этой проблемы? Я не изменил модель основных данных.

 NSMergeConflict for NSManagedObject with objectID '...' 
with oldVersion = 117 and newVersion = 118 and 
old object snapshot = ... and new cached row =  ...
  

Комментарии:

1. Можете ли вы дать краткое описание того, что делает ваш элемент traverseElement?

Ответ №1:

Конфликт слияния инкапсулирует конфликты, возникающие при попытке сохранить изменения в контексте управляемого объекта.

Существует две ситуации, в которых может возникнуть конфликт:

Между контекстом управляемого объекта и его кэшированным состоянием в памяти на уровне координатора постоянного хранилища. В этом случае конфликт слияния имеет исходный объект и кэшированный моментальный снимок, но не сохраняется моментальный снимок.

Между состоянием кэша в координаторе постоянного хранилища и внешним хранилищем (файл, база данных и т.д.). В этом случае конфликт слияния имеет кэшированный снимок и сохраненный снимок.

Смотрите документацию здесь.

Комментарии:

1. developer.apple.com/library/ios/documentation/CoreData /… нужна цитата

2. @Luonghuyd Хороший момент — это было некоторое время назад. Я исправил это. Тем не менее, нет необходимости голосовать против.

Ответ №2:

Это может быть вам полезно: http://www.duckrowing.com/2010/03/11/using-core-data-on-multiple-threads /.

В статье объясняется, как вы должны использовать многопоточность для сохранения.