Я использую частный управляемый объектный контекст для создания некоторых новых объектов в постоянном хранилище, а затем после сохранения частного MOC, объединяя их в основной MOC, используя mergeChangesFromContextDidSaveNotification
. Это отлично работает и обновляет пользовательский интерфейс по мере необходимости, а NSManagedObjectContextWillSaveNotification
здесь НЕ используется для mainMOC
.Как игнорировать изменения в mergeChangesFromContextDidSaveNotification в NSManagedObjectContextWillSaveNotification
Затем я вношу некоторые изменения в mainMOC
с использованием пользовательского интерфейса и прослушиваю NSManagedObjectContextWillSaveNotification
. Уведомление опубликовано, но оно содержит не только сделанные мной изменения, но и объекты, которые были объединены с PrivateMOC
, используя mergeChangesFromContextDidSaveNotification
.
Есть ли способ игнорировать изменения, которые были объединены из другого контекста в mainContext
, после следующих уведомлений contextDidChange
?
Вот установка:
- (void) loadData {
privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
privateContext.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextWillSave:)
name:NSManagedObjectContextWillSaveNotification
object: self.mainContext];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:record.recordType inManagedObjectContext: self.privateContext];
// fill in object
if ([self.privateContext hasChanges]) {
[self savePrivateContextAndMergeWithMainContext: self.privateContext];
}
}
- (void) savePrivateContextAndMergeWithMainContext: (NSManagedObjectContext *) privateContext {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(privateContextDidChange:) name:NSManagedObjectContextDidSaveNotification object:privateContext];
__block NSError *error = nil;
[privateContext performBlockAndWait:^{
NSLog(@"PrivateContext saved");
[privateContext save:&error];
}];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:privateContext];
if (error) {
NSLog(@"error = %@", error);
}
}
- (void) privateContextDidChange: (NSNotification *) notification{
[self.mainContext performBlockAndWait:^{
NSLog(@"merged into mainContext");
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
Это прекрасно работает и сохранение частного контекста и слияния в mainContext
не вызывает уведомления contextWillSave
. Но при редактировании данных из пользовательского интерфейса (на основном MOC) запускается уведомление и включает данные, которые ранее были сохранены с помощью частного MOC.
Надеюсь, что это ясно. Дайте мне знать, если я должен включить что-нибудь еще.
- ОБНОВЛЕНИЕ -
Похоже, что проблема с специально удаления объектов из частного контекста. После удаления из частного контекста и вызова mergeChangesFromContextDidSaveNotification
на основном MOC набор deletedObjects
mainMoc все еще показывает объект, который был удален. Это не происходит со вставками или обновлениями в частном контексте. Является ли это документированным где угодно? Каким может быть обходной путь?
Почему вы также наблюдаете за основным контекстом? Что вы делаете с этими изменениями? – Wain
Главный наблюдатель контекста должен слушать изменения, внесенные пользовательским интерфейсом, поэтому они могут быть переданы на сервер. Вот почему я не хочу, чтобы изменения в частном контексте отображались в основном слушателе контекста. Они не изначально, когда изменения объединяются в основной контекст, но похоже, что MOC по-прежнему отмечает их как «измененные», и при следующем сохранении основного контекста они отображаются в объекте уведомления. –
На самом деле проблема, похоже, больше связана с объектами * deleted * в фоновом контексте, а не вставлена. Удаления - вот что вызывает у меня эту проблему, поскольку они, похоже, зависают после того, как «mergeChangesFromContextDidSaveNotification:» называется –