我的表用于列出核心数据中的行。一切正常,我已经使用两种类型的数据加载到同一个表视图上。由于范围按钮更改,数据类型会更改。两个范围按钮一个显示已完成的任务,而另一个显示未决的任务我可以在桌面上搜索,更新。虽然只有完整的数据列表是可编辑的并且可以删除,但有时它工作正常,有时会出错,
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)
获取结果控制器初始化为,
- (NSFetchedResultsController *)fetchedResultsControllerWithPredicate:(NSPredicate *)predicate{
if (self.fetchedResultsControl != nil) {
NSLog(@"Here I am outside");
return self.fetchedResultsControl;
}
为tableview加载单元格的代码如下:
- (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;
}
NSFetchedResultsControllerDelegate调用的更新方法为;
- (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];
}
答案 0 :(得分:3)
我没有看到任何明显的错误,但在一个tableview中交换两个逻辑表是一个危险的设计,因为你必须非常小心tableview知道它的逻辑表已被更改。
您得到的错误表明tableview使用一个逻辑表的索引配置自己,但实际上是访问第二个逻辑表的数组,该数组更短。
您可以立即解决此问题,密切关注numberOfSections
和numberOfRowsInSection
等方法,以确保在切换逻辑表时这些方法能够正确更新。
最佳设计解决方案是使用两个单独的tableview和各自独立的数据源,然后根据需要将它们交换出来。