2

マスター詳細アプリケーション -

とそのデリゲート メソッドUITableViewControllerによって管理される があります。NSFetchedResultsControllerまた、テーブルビューの最初のセクションにUIWebView、埋め込みビデオを表示するセルが 1 つ追加されています。このセルは の一部ではありませんNSFetchedResultsControllerIFが呼び出されたときにステートメント内に追加し-tableView cellForRowAtIndexPath、最初のセクションと最初の行であるかどうかを確認します。ほとんどの場合、すべてがうまく機能します。行を選択して に表示したりDetailViewController、 からアイテムを削除しtableViewたり、 の情報を変更しDetailViewControllerたり、tableViewCellラベルを問題なく更新したりできます。

私の問題

セットアップ方法で問題が発生するのは、ファイルの最初のセクションから最後のオブジェクトを削除するときだけtableViewです。

エラー

CoreData: エラー: 重大なアプリケーション エラーです。-controllerDidChangeContent: の呼び出し中に、NSFetchedResultsController のデリゲートから例外がキャッチされました。無効な更新: セクション 0 の行数が無効です。更新後の既存のセクションに含まれる行数 (3) は、更新前にそのセクションに含まれる行数 (2) にプラスまたはマイナスの数値を指定する必要があります。そのセクションに挿入または削除された行数 (0 挿入、0 削除)、およびそのセクションに移動された、またはそのセクションから移動された行数 (0 移動、0 移動)。userInfo (ヌル)

コード

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

送信されたインデックス パスが最初の (ゼロ) セクション用であるかどうかを確認するには、さらに条件付きコードが必要です。そうである場合、FRC に「間違った」行番号が与えられています。これは、テーブル ビューに 1 つの行数を伝え、FRC が別の行数を理解するためです。

基本的に、テーブル ビューからインデックス パスを受け取るすべての場所でセクションを確認== 0し、同じセクションで新しいインデックス パスを作成し、それrow - 1を使用して FRC 内のオブジェクトにアクセスします。

逆に、FRC からインデックス パスを受け取ると、row + 1それを使用してテーブル ビューに挿入/削除/移動を要求する前に必要になります。

于 2013-07-15T08:37:00.777 に答える
0

あなたの質問では、次のように述べています。

tableView の最初のセクションから最後のオブジェクトを削除すると

これにより、例外が次のように述べていることが期待されます(強調を追加):

CoreData: エラー: 重大なアプリケーション エラーです。-controllerDidChangeContent: の呼び出し中に、NSFetchedResultsController のデリゲートから例外がキャッチされました。無効な更新: セクション 0 の行数が無効です。更新後の既存のセクションに含まれる行数 (0)は、更新前にそのセクションに含まれる行数(1)にプラスまたはマイナスの数値を指定する必要があります。そのセクションに挿入または削除された行数(0 挿入、1 削除)、およびそのセクションに移動した行数またはそのセクションから移動した行数 (0 移動、0 移動)。userInfo (ヌル)

例外は、行が追加されずに行数が 2 から 3 に増加していることを示しているため、テーブル ビュー コードではなく、モデル レイヤーでエラーが発生していると思います。あなたのテーブルビューコードは私には素晴らしいようです。

于 2013-07-15T01:31:31.863 に答える