Skip to content

Instantly share code, notes, and snippets.

@uliluckas
Created July 17, 2012 15:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uliluckas/3129990 to your computer and use it in GitHub Desktop.
Save uliluckas/3129990 to your computer and use it in GitHub Desktop.
mergeChangesFromContextDidSaveNotification with core data bug workarounds
// See http://lists.apple.com/archives/cocoa-dev/2008/Jun/msg00237.html for bugs below
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification*)notification {
NSManagedObject *object;
NSSet* updates;
// Workaround bug 5982319
// Fault in all updated objects because chnages to faults won't trigger fetchedResultsControlle
updates = [notification.userInfo objectForKey:NSUpdatedObjectsKey];
for (object in updates) {
[[self.roManagedObjectContext objectWithID:[object objectID]] willAccessValueForKey:nil];
}
[self.roManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
// Workaround for bug 5937572
// Clean up unexpected 'maintainance' after merge.
// mergeChangesFromContextDidSaveNotification tries to maintain the object models relations
// and messes it up. As we only merge consistent changes into a clean context no 'after merge'
// maintainance is needed. We can safely revert all changes.
// To still fire all changes, processPendingChanges must be called first though.
updates = self.roManagedObjectContext.updatedObjects;
for (object in updates) {
[self.roManagedObjectContext refreshObject:object mergeChanges:NO];
}
// Save the remaining changes (deletes) to get our context clean again
NSError *error = nil;
self.inCleanup = YES;
[self.roManagedObjectContext save:&error];
self.inCleanup = NO;
if (error) {
PRLog(@"Error saving merged changes: %@", error);
}
}
- (void)contextDidSave:(NSNotification *)notification {
NSManagedObjectContext *savingContext = (NSManagedObjectContext *) [notification object];
if (savingContext.persistentStoreCoordinator != self.persistentStoreCoordinator) {
// Ignore saving of contexts on different store coordinators
return;
}
if (self.roManagedObjectContext == savingContext) {
if (!self.inCleanup) {
PRLog(@"####### Write operation on roManagedObjectContext detected !!!!!!");
}
// No need to merge chnages from our our own context
return;
}
if (dispatch_get_current_queue() != self.writeQueue) {
PRLog(@"####### Write operation on wrong queue detected !!!!!!");
}
[self performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification waitUntilDone:YES];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment