0

大家好,所以我的 NSFetchedResultsController 在 3.1 SDK 下工作正常,但是我开始遇到一些奇怪的错误,特别是当我在 3.0 下尝试时在委托方法中。我已经确定这与 NSFetchedResultsControllerDelegate 方法有关。这就是我设置的。

inEditingMode 的内容与我实现向表中添加另一个静态部分的方式有关。

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type{
    NSIndexSet *sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex];

    if(self.inEditingMode){
        sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex + 1];
    }

    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            [self.tableView reloadData];
            break;

    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
    NSIndexPath *relativeIndexPath = indexPath;
    NSIndexPath *relativeNewIndexPath = newIndexPath;

    if(self.inEditingMode){
        relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section + 1];
        relativeNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section + 1];
    }

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:relativeNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:relativeIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            [self.tableView reloadData];
            break;
    }
}


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

当我将实体添加到托管对象上下文时,我收到以下错误:

Serious application error.  Exception was caught during Core Data change processing: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1) with userInfo (null)

我在 objc_exception_throw 上放了一个断点,崩溃似乎发生在 controllerDidChangeContent 内部。

如果我注释掉所有 self.tableView 方法,并在 controllerDidChangeContent 中放置一个 [self.tableView reloadData],一切都会按预期工作。

有人知道为什么会这样吗?

4

1 回答 1

2

在 NSFetchedResultsController 的文档中,特别提到了 3.0 实现中的一个错误,该错误导致控制器报告的节数与 UITableView 预期的节数之间存在差异。这是他们提供的解决方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    NSUInteger count = [[<#Fetched results controller#> sections] count];
    if (count == 0) {
        count = 1;
    }
    return count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    NSArray *sections = [<#Fetched results controller#> sections];
    NSUInteger count = 0;
    if ([sections count]) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
        count = [sectionInfo numberOfObjects];
    }
    return count;
}

请注意,OS 3.1 不需要此解决方法,因此这可以解释为什么您没有看到错误。仅当 sectionNameKeyPath 设置为 nil 时,3.0 中才需要解决方法。如果您正在为 sectionNameKeyPath 设置一个值,那么这可能不是问题所在。

于 2010-04-01T05:35:31.440 回答