NSFetchedResultsController not firing delegate met

2020-07-18 08:21发布

问题:

I have an NSFetchedResultsController and a few operations that inserts and updates managed objects on separate threads via NSOperationQueue.

The FRC looks like this, note that I have set the cache to nil:

[NSFetchedResultsController deleteCacheWithName:nil];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];

Each threaded operation has its own managed object context and fires mergeChangesFromContextDidSaveNotification to the main MOC each time it saves changes.

The code that I use to merge contexts looks like this:

- (void)mergeContextChanges:(NSNotification *)notification
{
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];

    if([NSThread isMainThread] == NO)
    {
        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
        return;
    }

    NSSet *updated = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];

    for(NSManagedObject *thing in updated)
    {
        NSLog(@"Background thread updated %@", [thing description]);
    }

    for(NSManagedObject *thing in updated)
    {
        [[context objectWithID:[thing objectID]] willAccessValueForKey:nil];
    }

    [context mergeChangesFromContextDidSaveNotification:notification];
}

I can confirm by looking at the logs that each time the background operations insert or update data, my mergeContextChanges: method is being called with the proper insert/update values.

The problem is that while merging inserts are firing the FRCs delegate methods (ex. controllerDidChangeContent:) properly, merging updates doesn't signal the FRC to fire its delegate methods.

Strange enough, I can also confirm that the FRC fires its delegates properly if I run the updates on the main thread using the main MOC.

How can I make the FRC fire its delegate methods when updated MOCs are merged?

More Info: Looks like using any MOC other than the main MOC and trying to merge updates to the main MOC has the same results; the FRC refuses to notice it.

回答1:

Oh..... man.

It looks like accessing the main MOC from within my threaded operations (even if it's for a task unrelated to the data I was trying to update) causes this weird behavior.

I hope this helps anyone else that runs into this problem.