views:

34

answers:

1

I am presenting table view contents using NSFetchedResultsController which has a predicate:

[NSPredicate predicateWithFormat:@"visible == %@", [NSNumber numberWithBool:YES]]

On background thread using separate NSManagedObjectContext I update few of the entities and change theirs visible value from NO to YES. Save, merge changes in main thread's NSManagedObjectContext. But NSFetchedResultsController's fetchedObjects doesn't change. Also controller doesn't call -controller:didChangeObject:... on delegate. If entities are updated on main thread in identical manner (my test app calls the same method), everything works as expected.

Also Notification's NSUpdatedObjectsKey contains those objects objects.

Currently the only solutions I've found is to call for each of NSUpdatedObjectsKey entities:

NSManagedObjectContext *context = ... // main thread context
[context existingObjectWithID:[object objectID] error:nil]

This issue is only with updated objects which previously didn't match the predicate.

Am I missing something obvious?

A: 

Turns out main NSManagedObjectContext didn' t event fire NSManagedObjectContextObjectsDidChangeNotification for updated objects because it is not done for faulted objects.

Generic fix (or keep a track of object IDs that needs this treatment):

NSManagedObjectContext *context = [self managedObjectContext];
for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) {
  [[context objectWithID:[object objectID]] willAccessValueForKey:nil];
}

[context mergeChangesFromContextDidSaveNotification:notification];

From NSManagedObject Class Reference:

You can invoke this method with the key value of nil to ensure that a fault has been fired, as illustrated by the following example.

ampatspell