0

やあみんな、3.1 SDKでNSFe​​tchedResultsControllerが正常に動作するようになりましたが、特に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メソッドをコメントアウトし、単一の[self.tableView reloadData]をcontrollerDidChangeContent内に配置すると、すべてが期待どおりに機能します。

なぜこれが起こっているのかについて誰かが何か考えを持っていますか?

4

1 に答える 1

2

NSFetchedResultsController のドキュメントには、コントローラーによって報告されるセクション数と UITableView によって期待されるセクション数との間に不一致が生じる 3.0 実装のバグについて具体的に言及されています。これは彼らが提供する回避策です:

- (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 に答える