У меня есть интересная проблема, с которой я не могу найти решение - у меня есть два контекста управляемых объектов, «основной» и «резервный». «Главная» создается с помощью NSMainQueueConcurrencyType, а «поддержка» создается с помощью «NSPrivateQueueConcurrencyType». Кроме того, «backing» был установлен как родительский элемент main.NSManagedObjectContextDidSaveNotification merging and deletedObjects
Я хочу сделать (потенциально дорого) операции записи на MOC резервного копирования, а затем внести эти изменения (когда они завершены) в главный контекст и, таким образом, обновить пользовательский интерфейс из-за использования NSFetchedResultsController. Моя проблема заключается в следующем: кажется, что после вызова mergeChangesFromContextDidSaveNotification свойство deletedObjects на основном MOC заполняется всеми объектами, которые были удалены в фоновом режиме, используя резервную очередь.
В качестве примера, вот какой-то код.
[appDelegate.backingContext performBlock:^{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Parent"];
NSArray *objects = [appDelegate.backingContext executeFetchRequest:fetchRequest error:nil];
for(Parent *parent in objects) {
NSMutableOrderedSet *children = [parent mutableOrderedSetValueForKey:@"children"];
for(Child *child in children) {
[appDelegate.backingContext deleteObject:child];
}
[children removeAllObjects];
for(int i=0;i<3;i++) {
Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child"
inManagedObjectContext:appDelegate.backingContext];
child.name = [NSString stringWithFormat:@"Child #%i", i];
[children addObject:child];
}
}
[appDelegate.backingContext save:nil];
}];
и на моем приложение делегата
- (void)mergeContextChanges:(NSNotification *)notification {
[self.mainContext performBlock:^{
NSLog(@"Before merge: updates - %i, inserts - %i, deletes - %i",
self.mainContext.updatedObjects.count,
self.mainContext.insertedObjects.count,
self.mainContext.deletedObjects.count);
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
NSLog(@"After merge: updates - %i, inserts - %i, deletes - %i",
self.mainContext.updatedObjects.count,
self.mainContext.insertedObjects.count,
self.mainContext.deletedObjects.count);
}];
}
Вот что говорит журнал после того, как изменения были объединены -
2013-04-03 00:51:40.476 CoreDataTest[41617:c07] Before merge: updates - 0, inserts - 0, deletes - 0
2013-04-03 00:51:40.477 CoreDataTest[41617:c07] After merge: updates - 0, inserts - 0, deletes - 3
Вы заметите, что основной контекст сообщает 3 объекта в ожидании для удаления. Насколько я могу судить, это неверно - не следует mergeContextChanges: заставить состояние контекста (в противном случае полностью нетронутого) не отображать ожидающие изменения? Суть этого метода заключается в том, что изменения уже были зафиксированы в постоянном хранилище.
Что мне здесь не хватает?
Да, после немного более продуманного, это имеет смысл. Возможно, MOC не должен отмечать объект как ожидающее удаление, если он не перезапущен с MOC в первую очередь. Я могу понять, почему, если бы вы хотели это сделать, это может появиться в отношениях, или кто-то может иметь ссылку на него.Но если это полностью внутреннее состояние MOC, я не понимаю, почему он должен быть отмечен. – dpratt
Вы когда-нибудь находили путь, поэтому слияние не вызывает флаг hasChanges ?. (Благодаря!) –