tags:

views:

653

answers:

2

Hi all. Im currently developing a holiday journal like application which stores each place you have visited by its type. For instance, a restaurant name should be stored under 'food' section. I have managed to work with core data and create the table with no problem. However, the problem is whenever i try to change the type of a place (thus tableview need to reorder), i would get an error message:

2009-07-22 21:04:58.150 HolidayTest[8662:20b] Serious application error. Exception was caught during Core Data change processing: * -[NSCFArray removeObjectAtIndex:]: index (4) beyond bounds (4) with userInfo (null) 2009-07-22 21:04:58.151 HolidayTest[8662:20b] * Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray removeObjectAtIndex:]: index (4) beyond bounds (4)'

I know the fetch results controller's delegate has updated the table. But the problem is the fetch controller has not updated its own section and row data. The easy way is to tell the fetch results controller to refetch its data if user changes its type. However, its not efficient way to manage the data.

Could please anyone give my some help on this.

A: 

It is difficult to tell exactly what you mean here, but it seems as though you're attempting to remove beyond the end of your array. It's hard to know what you would be doing that is causing that.

If I were to implement this, I would

A) Remove the entry from the table:

[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];

B) Remove the entry from the data structure.

C) Modify the data (title and whatever else).

D) Add the entry where it needs to be in the data structure.

E) Add the entry where it should be in the table:

[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];

Hope that helped. I'll keep an eye if you update the question.

TahoeWolverine
A: 

Thank you for your answer TahoeWolverine. Here is the code where i change the type of a place where user selects a row on a tableview to change its type.

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:selected inSection:0]; UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath]; checkedCell.accessoryType = UITableViewCellAccessoryNone;

    [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
    selected = indexPath.row; NSManagedObject *aType = [siteType objectAtIndex:indexPath.row]; self.site.type = [aType valueForKey:@"name"]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; [self.delegate TypeSelectionController:self didChangeType:YES]; }

this code corresponds to the fetch results controller's delegate which runs the following code

  • (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { [self.tableView beginUpdates]; }

  • (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    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:
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
     [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
     break;
    

    }

}

  • (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id) )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    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)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView endUpdates]; }

then i will the get the error message.......

joyce