Created
July 17, 2012 15:12
-
-
Save uliluckas/3129990 to your computer and use it in GitHub Desktop.
mergeChangesFromContextDidSaveNotification with core data bug workarounds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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