尝试将新表行插入节中的异常抛出

时间:2010-10-12 01:36:02

标签: iphone cocoa cocoa-touch uitableview core-data

我似乎遇到了一个非常奇怪的问题,只有在尝试将新的NSManagedObject插入新的部分时才会出现这个问题。基本上我的部分是几天,单个细胞与时间相关联。当我将一个对象移动到当前没有与该日期相关联的另一个对象(表格行)的那一天时,该表需要创建一个新的部分并移动该行。而不是正确地发生这种情况我得到以下内容:

  

严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常。 * - [NSMutableArray removeObjectAtIndex:]:索引1超出bounds [0 .. 0] with userInfo(null)

为当前没有其他对象的一天插入一个新对象似乎工作正常。

问题似乎出现在这段代码中,但我似乎无法弄清楚它有什么问题。似乎首先使用插入和删除调用controller:didChangeSection:...,然后使用NSFetchedResultsChangeMove调用controller:didChangeObject:...。所以顺序是:

NSFetchedResultsChangeInsert(在didChangeSection中) NSFetchedResultsChangeDelete(在didChangeSection中) NSFetchedResultsChangeMove(在didChangeObject中)

/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.plainTableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath
 forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tv = self.plainTableView;

switch(type) {
    case NSFetchedResultsChangeInsert:
        [tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

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

    case NSFetchedResultsChangeUpdate:
        [self configureCell:(UITableViewCell *)[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        // Reloading the section inserts a new row and ensures that titles are updated appropriately.
        [tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type {
    switch(type) {
    case NSFetchedResultsChangeInsert:
        [self.plainTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.plainTableView endUpdates];
}

我认为这只是标准的模板代码。有谁知道可能出现什么问题?

实际上,当尝试将新行插入已存在的某一天时,也会发生这种情况,但是在为尚未存在的日期插入新行/对象时也是如此。

2 个答案:

答案 0 :(得分:5)

我似乎通过从最新版本的CoreDataBooks复制以下代码来解决这个问题:

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

在此之前,这里的代码是:

    case NSFetchedResultsChangeMove:
        [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        // Reloading the section inserts a new row and ensures that titles are updated appropriately.
        [tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
        break;

答案 1 :(得分:1)

我认为你在这里有一个概念问题。

应该调用controller:didChange...方法以响应由获取的结果控制器(FRC)检测到的数据模型的变化。我很确定您的问题是您在更改基础数据之前或之后更改表。

节和行不是表的属性,它们是由FRC构造的数据的属性。如果需要添加一个部分,则需要先将其添加到数据中,然后让FRC委托方法使表更新。该表反映了数据模型,而不是反过来。

如果您不这样做,FRC将报告错误的部分或行数,并导致表格因您看到的错误而崩溃。