2

主从申请 -

我有一个UITableViewController由 anNSFetchedResultsController及其委托方法管理的。我在表格视图的第一部分还有一个额外的单元格,其中有一个UIWebView显示嵌入视频的单元格。此单元格不是NSFetchedResultsController. 当被调用时,我将它添加到一个IF语句-tableView cellForRowAtIndexPath中,检查它是否是第一部分和第一行。在大多数情况下,一切都很好。我可以选择一行并将其显示在 中DetailViewController,我可以从 中删除项目tableView,我可以更改 中的信息DetailViewController并且tableViewCell标签更新没有任何问题。

我的问题

唯一一次我对它的设置方式有疑问是,当我从tableView.

错误

CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间,从 NSFetchedResultsController 的委托中捕获了一个异常。无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (3) 必须等于更新前该节中包含的行数 (2),加上或减去数字从该部分插入或删除的行数(0 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

代码

numberOfRowsInSection

这是我检查视频是否可用的地方,如果该部分为 0,则返回 1 个额外行。否则从NSFetchedResultsController. 我假设这是我的问题所在。但是,我不知道如何解决它。因为我通过NSFetchedResultsController委托方法管理它,所以我可以在 switch 语句的“类型”内部做些什么?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0 && self.videoInfoReceived == YES) {
        id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [secInfo numberOfObjects] + 1;
    } else {
        id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [secInfo numberOfObjects];
    }

}

NSFetchedResultsController 代表

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

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

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"didChangeSection - ChangeDelete");
            break;
    }
}

- (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:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"didChangeObject - ChangeInsert");
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"didChangeObject - ChangeDelete");
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            NSLog(@"didChangeObject - ChangeUpdate");
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"didChangeObject - ChangeMove");
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}
4

2 回答 2

1

You need more conditional code to check if any index path you're sent is for the first (zero) section. If it is, the FRC is being given the 'wrong' row number because you have told the table view one row count and the FRC understands a different one.

Basically, everywhere you receive an index path from the table view, check the section, if it == 0, create a new index path with the same section and row - 1 and use that to access the objects in the FRC.

Conversely, when you receive an index path from the FRC you need row + 1 before you can use it to ask the table view to insert/delete/move.

于 2013-07-15T08:37:00.777 回答
0

在您的问题中,您说:

当我从 tableView 的第一部分中删除最后一个对象时

这将导致我期望异常说明以下内容(强调添加):

CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间,从 NSFetchedResultsController 的委托中捕获了一个异常。无效更新:第 0 节中的行数无效。更新后现有节中包含的行数(0)必须等于更新前该节中包含的行数 (1),加上或减去数字从该部分插入或删除的行数(0 插入,1 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

因为异常表明行数从 2增加到3 而没有添加任何行,所以我认为您的错误出现在模型层而不是表视图代码中。您的表格视图代码对我来说看起来很棒。

于 2013-07-15T01:31:31.863 回答