iphone – 更新UITableView会导致异常

我有UITableViewController子类并实现以下

> NSFetchedResultsController及其委托
> tableView:sectionForSectionIndexTitle:atIndex:
> tableView:titleForHeaderInSection:

在controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:

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

在给定实体的数据模型中,我有临时属性uppercaseFirstLetterOfName,它将返回持久属性的第一个字母.

这就是为表项和侧索引实现按字母顺序排列的部分.

现在如果我有一个部分的单个记录,那么我重命名它以便它将改变部分,我得到以下异常,这发生在NSFetchedResultsChangeMove之后的某个地方.

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-984.38/UITableView.m:774

Exception was caught during Core Data
change processing: Invalid update:
invalid number of rows in section 0.
The number of rows contained in an
existing section after the update (1)
must be equal to the number of rows
contained in that section before the
update (1), plus or minus the number
of rows inserted or deleted from that
section (0 inserted, 1 deleted).

有任何想法吗?

UPD更多代码:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    NSInteger count = [[fetchedResultsController sections] count];
    return count;
}

- (NSInteger)tableView:(UITableView *)tableView
                         numberOfRowsInSection:(NSInteger)section 
{
    NSInteger numberOfRows = 0;
    if ([[fetchedResultsController sections] count] > 0) 
    {
        id <NSFetchedResultsSectionInfo> sectionInfo =
              [[fetchedResultsController sections] objectAtIndex:section];
        numberOfRows = [sectionInfo numberOfObjects];
    }
    return numberOfRows;
}

    NSSortDescriptor* sortByWordDescriptor = [[NSSortDescriptor alloc] 
                        initWithKey:@"subject" ascending:YES];
    NSArray* sortArray = [[NSArray alloc]
                        initWithObjects:sortByWordDescriptor, nil];
    [fetchRequest setSortDescriptors:sortArray];

    NSFetchedResultsController* controller = [[NSFetchedResultsController alloc]
                        initWithFetchRequest:fetchRequest 
                        managedObjectContext:managedObjectContext 
                        sectionNameKeyPath:@"uppercaseFirstLetterOfName" 
                        cacheName:@"Root"];

UPD(修补):
目前我修改了这样的代码:

    case NSFetchedResultsChangeMove:
        NSUInteger tableSectionCount = [self.tableView numberOfSections];
        NSUInteger modelSectionCount = [[controller sections] count];
        if (modelSectionCount > tableSectionCount) 
        {
            [self.tableView insertSections:[NSIndexSet
                                indexSetWithIndex:[newIndexPath section]]
                                withRowAnimation:UITableViewRowAnimationNone];
        }
        else if(modelSectionCount < tableSectionCount)
        {
            if (tableSectionCount > 1) 
            {
                [self.tableView deleteSections:[NSIndexSet
                                 indexSetWithIndex:[indexPath section]] 
                                 withRowAnimation:UITableViewRowAnimationNone];
            }
        }
        [tableView deleteRowsAtIndexPaths:[NSArray
                                 arrayWithObject:indexPath]
                                 withRowAnimation:UITableViewRowAnimationFade];
        [tableView insertRowsAtIndexPaths:[NSArray
                                 arrayWithObject:newIndexPath] 
                                 withRowAnimation:UITableViewRowAnimationFade];

        break;

到目前为止没有崩溃,但这是正确的解决方案吗?

最佳答案 我想我知道你发生了什么事.确保你有:

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

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

文档说明了“beginUpdates”方法:

Call this method if you want subsequent insertions, deletion, and selection operations (for example, cellForRowAtIndexPath: and indexPathsForVisibleRows) to be animated simultaneously.

这就是你正在做的事情:

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

干杯

点赞