The reason this happens is due to the way mergeChangesFromContextDidSaveNotification: handles updated objects. NSManagedObjectContext stores a record of objects that are used in context, they are called registered objects ( NSManagedObjectContext has methods for accessing and conditionally fetching registered objects). mergeChangesFromContextDidSaveNotification: only processes updates for objects that are registered in the context. This affects the NSFetchedResultsControllers , which explains the cause of the problem.
Here's how it goes:
FRC is configured with a predicate that does not match all objects (thus preventing the possibility that objects that do not match the predicate will be registered in the FRC context).
The second context does an object change, which means that it now matches the FRC predicate. The second context is maintained.
The FRC context processes NSManagedObjectContextDidSaveNotification , but only updates registered objects, so it does not update the object that now matches the FRC predicate.
FRC does not perform another selection when saving, therefore, does not know that the updated object must be included.
Correction
The solution is to retrieve all updated objects when merging the notification. Here is an example of a merge method:
-(void)mergeChanges:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue, ^{ NSManagedObjectContext *savedContext = [notification object]; NSManagedObjectContext *mainContext = self.managedObjectContext; BOOL isSelfSave = (savedContext == mainContext); BOOL isSamePersistentStore = (savedContext.persistentStoreCoordinator == mainContext.persistentStoreCoordinator); if (isSelfSave || !isSamePersistentStore) { return; } [mainContext mergeChangesFromContextDidSaveNotification:notification];
source share