"didChangeSection:" The delegate method NSfetchedResultsController is not called

I have a standard controller with a split view, with a detailed view and a table view. Clicking the button in the detailed view may cause the object to change its placement in the viewing order of the table. This works fine if the resulting change to the order does not add or remove a section. That is, an object can change its ordering in a section or switch from one section to another. These order changes work without problems. But if an object tries to move to a partition that does not exist yet, or the last object leaves the partition (therefore, the partition that it was deleted must be deleted), the application crashes.

NSFetchedResultsControllerDelegate has methods for handling the added and deleted partitions that should be called in these cases. But for some reason, these delegate methods are not called.

The code in question is a template:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"willChangeContent");
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@"didChangeSection");

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {    
NSLog(@"didChangeObject");

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"didChangeContent");
    [self.tableView endUpdates];

    [detailViewController.reminderView update];
}

Launching the application and subsequent output of the last object from the section leads to the following output:

2011-01-08 23:40:18.910 Reminders[54647:207] willChangeContent
2011-01-08 23:40:18.912 Reminders[54647:207] didChangeObject
2011-01-08 23:40:18.914 Reminders[54647:207] didChangeContent
2011-01-08 23:40:18.915 Reminders[54647:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1145.66/UITableView.m:825
2011-01-08 23:40:18.917 Reminders[54647:207] Serious application error.  Exception was caught during Core Data change processing: Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (5) must be equal to the number of sections contained in the table view before the update (6), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)

As you can see, "willChangeContent", "didChangeObject" (moving the object in question), and "didChangeContent" were called properly. Based on Apple's NSFetchedResultsControllerDelegate documentation, “didChangeSection” should have been called before “didChangeObject,” which would have prevented the exception that caused the failures.

So, I think the question is, how can I guarantee that didChangeSection will be called?

Thanks in advance for your help!

+5
2

sectionNameKeyPath. , sectionNameKeyPath , . , NSFetchedResultsController NameKeyPath. .

+1

( transient NameKeyPath), , . iOS 4.2.1... , FRC iOS 3.X, [tableView reloadData] controllerDidChangeContent:. . FRC

, ​​ .

+1

All Articles