代码之家  ›  专栏  ›  技术社区  ›  Nimrod

尝试将新表行插入节时引发异常

  •  1
  • Nimrod  · 技术社区  · 15 年前

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

    严重的应用程序错误。在调用-ControllerIDChangeContent:期间,从NSFetchedResultsController的委托捕获到异常。 * -[NSMutableArray removevobjectatindex:]:索引1超出界限[0。。0]用户信息为(空)

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

    controller:didChangeSection:... 似乎是先用insert和delete调用然后 controller:didChangeObject:... 使用NSFetchedResultsChangeMove调用。所以顺序是:

    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 回复  |  直到 15 年前
        1
  •  1
  •   TechZen    15 年前

    我觉得你在概念上有问题。

    这个 controller:didChange...

    节和行不是表的属性,它们是由FRC组织的数据的属性。如果需要添加节,则需要先将其添加到数据中,然后让FRC delegate方法更新表。表反映了数据模型,而不是相反。

        2
  •  5
  •   Nimrod    15 年前

        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;
    
    推荐文章