My table is used to list the rows from the core data. Everything works fine, I have used two types of data to load on the same table view. The data types change on account of the scope button change. Two scope buttons one displays completed tasks while other displays pending taks. I can search, update on the table. While only completed list of datas are editable and can be deleted, sometimes it works fine and sometimes it gives error as such,
Serious application error. An exception was caught from the delegate of
NSFetchedResultsController during a call to -controllerDidChangeContent:. *** -
[NSMutableArray insertObject:atIndex:]: index 4 beyond bounds for empty array with
userInfo (null)
The fetch result controller is initialised as,
- (NSFetchedResultsController *)fetchedResultsControllerWithPredicate:(NSPredicate *)predicate{
if (self.fetchedResultsControl != nil) {
NSLog(@"Here I am outside");
return self.fetchedResultsControl;
开发者_开发百科
}
The code to load the cell for tableview is as :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
CustomCell *cell =(CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil];
for (id currentObject in topLevelObjects) {
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell=(CustomCell *)currentObject;
break;
}
}
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
And the update method called by the NSFetchedResultsControllerDelegate is as;
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.listingTable beginUpdates];
NSLog(@"Changed content");
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id < NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.listingTable insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.listingTable deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@"Changed content switch case");
UITableView *tableView = self.listingTable;
switch(type) {
case NSFetchedResultsChangeInsert:
[self.listingTable insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationTop];
break;
case NSFetchedResultsChangeDelete:
[self.listingTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:(CustomCell *)[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[self.listingTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.listingTable insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"Changed Content");
[self.listingTable endUpdates];
}
I don't see any obvious errors but swapping out two logical tables in one tableview is a dangerous design because you have to be very careful that tableview knows that its logical table has been changed.
The error you are getting suggest that the tableview is configuring itself using one the index of one logical table but is actually accessing the array of the second logical table which is shorter.
Your immediate solution it to look closely at the methods like numberOfSections
and numberOfRowsInSection
to make sure that those update properly when you switched logical tables.
The best design solution is to use two separate tableviews with their own separate data source and then swap them out as needed.
精彩评论