NSFetchedResultsController not firing delegate method after merging update from background thread
Asked Answered
H

1

4

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.

Hygrophilous answered 7/10, 2011 at 2:42 Comment(0)
H
3

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.

Hygrophilous answered 7/10, 2011 at 18:47 Comment(3)
Could you explain what do you mean with the main MOC from within my threaded operations? I'm having the same issue here and I can't figured out a solution. Thank you in advance.Jerriejerrilee
you should always create a new Managed Object Context for each thread. You should NOT use one Managed Object Context across threads no matter what.Hygrophilous
This post https://mcmap.net/q/533929/-nsfetchedresultscontroller-attempting-to-insert-nil-object gives advice from an Apple Technical Support Engineer on how to debug multi-thread issues.Inroad

© 2022 - 2024 — McMap. All rights reserved.