views:

37

answers:

1

I am quite familiar with regular usage patterns of Core Data, but recently stumbled upon a problem: Imagine a simple case where I have an Entity of person, with 2 string attributes name and company. I want to make a UITableView sorted by names and divided into sections by company name. Sound simple enough:

...
personFetchController_ = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                             managedObjectContext:mainDataCenter.managedObjectContext
                                                               sectionNameKeyPath:@"company"
                                                                        cacheName:@"PersonListCache"];      
NSError *error = nil;
if (![personFetchController_ performFetch:&error])
{
    LogError(@"Error fetching persons: %@", [error localizedDescription]);
}
personFetchController_.delegate = self;

I register as delegate to listen to changes, especially changes to sections:

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    NSIndexSet *sections = [NSIndexSet indexSetWithIndex:sectionIndex];
    switch (type) 
    {
        case NSFetchedResultsChangeInsert:
            [personTableView_ insertSections:sections withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [personTableView_ deleteSections:sections withRowAnimation:UITableViewRowAnimationFade];
        default:
            break;
    }
}

It works very well when I add / remove / change the name of a person, but if I change a person's company name (which means to move from one section to another), the app crashes, saying after an insert, the number of rows in the section needs to be the old value plus one.

Anyone got this working right?

A: 

the code which leads to this crash is most likely not in this method.

Please post the code of this method:

-(void)controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:

especially how do you respond to changes with a type of NSFetchedResultsChangeMove?

in the Apple-Documentation for NSFetchedResultsControllerDelegate they use this for didChangeObject:...

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

Before I found out that the Apple-Documentation contains almost all code necessary for NSFetchedResultsController I used some code from the web, I guess from some tutorial, which caused a crash at rare occurences. After some time I found out I could trigger this when moving the one and only object in the first section (which will be deleted) to the second section (which will be the new first section).

Since then I read and search Apple-Documentation first before I read tutorials ^^

fluchtpunkt