user4951
user4951

Reputation: 33050

NSFetchedResultsController do not get updated when the managedobjectcontext change

I make a program where I sometimes moves some anchor to another

When I move those anchors I would recompute distance of bizs nearby the 2 anchors (before and after anchors). The computation is done in background

I used this standard code to update stuff

+(void)commit {
    // get the moc for this thread

    [Tools breakIfLock];
    NSManagedObjectContext *moc = [self managedObjectContext];
    NSThread *thread = [NSThread currentThread];

    DLog(@"threadKey commit%@" , [[self class]threadKey]);

    if ([thread isMainThread] == NO) {
        // only observe notifications other than the main thread
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
    }

    NSError *error;
    if (![moc save:&error]) {
        CLog(@"Error in Saving %@", error);
        DLog(@"What the hell error is it");
    }
    else{

    }

    if ([thread isMainThread] == NO) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc];
    }
    //[GrabClass StopNetworkActivityIndicatorVisible];

}

+(void)contextDidSave:(NSNotification*)saveNotification {

    dispatch_async(dispatch_get_main_queue(), ^{
        BadgerNewAppDelegate *delegate = [BNUtilitiesQuick appDelegate];
        DLog (@"currentThreadinContextDidSave: %@",[self threadKey]); 
        NSManagedObjectContext *moc = delegate.managedObjectContext; //delegate for main object
        CLog(@"saveNotification : %@",saveNotification);
        [moc mergeChangesFromContextDidSaveNotification:saveNotification];
    });


    //[moc performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:saveNotification waitUntilDone:YES];
}

I break point and see that distances did get updated. Everything is fine

However the NSFetchedResultsController fetchedObjects doesn't seem to get updated and still use the old value.

How can that be?

Also the

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    DLog(@"controllerWillChangeContent: %@", controller);
    [self.tableViewA beginUpdates];
}

is never called even though the NSManagedObjectContext has changes.

Well actually I wasn't sure if the managedObjectContext has changed or not. How do I know? I mean will change in managedObjectContext ensure changes in fetchController.fetchedObjects.

There is no caching as far as I know. How can I be sure of that too?

Upvotes: 1

Views: 3253

Answers (1)

stephen
stephen

Reputation: 1061

The NSFetchedResultsController documentation for fetchedObjects property states:

The results array only includes instances of the entity specified by the fetch request (fetchRequest) and that match its predicate. (If the fetch request has no predicate, then the results array includes all instances of the entity specified by the fetch request.)

The results array reflects the in-memory state of managed objects in the controller’s managed object context, not their state in the persistent store. The returned array does not, however, update as managed objects are inserted, modified, or deleted.

Availability Available in iOS 3.0 and later.

I can't say what the appropriate workaround is. My first thought is to call performFetch: in controllerDidChangeContent: in the delegate implementation.

The fetchedObjects array appears to update simply by overriding controllerDidChangeContent: with an empty implementation. This is the case using both the iPad and the iPad simulator for iOS 5.1.

There's clearly some discrepancy between the documentation and what I have observed. I have no explanation. Sorry. I can only suggest that you perform the fetch in controllerDidChangeContent: just to be safe.

Upvotes: 4

Related Questions