0

データソースとしてNSFetchedResultsControllerを使用しており、カスタムUITableViewControllerにNSFetchedResultsControllerDelegateを実装しています。sectionNameKeyPathを使用して、結果セットを複数のセクションに分割しています。

私のメソッドの1つでは、コンテキストにいくつかのオブジェクトを追加しています。これらはすべて新しいセクションにあります。オブジェクトを保存した時点で、デリゲートメソッドが適切に呼び出されています。イベントの順序:

// -controllerWillChangeContent: fires
[self.tableView beginUpdates]; // I do this

// -controller:didChangeSection:atIndex:forChangeType: fires for section insert
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];

// -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath fires many times
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                withRowAnimation:UITavleViewRowAnimationFade]; // for each cell

// -controllerDidChangeContent: fires after all of the inserts
[self.tableView endUpdates];  // <--- Where things go terribly wrong!!!

最後の呼び出し「endUpdates」で、アプリケーションは常に次のようにクラッシュします。

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

テーブルの更新が何らかの形でNSFe​​tchedResultsControllerデータと同期していないようで、問題が発生します。NSFetchedResultsControllerDelegateのドキュメントをフォローしていますが、機能していません。それを行う正しい方法は何ですか?

更新:このバグを示すテストプロジェクトを作成しました。NSBoom.zipからダウンロードできます。

4

2 に答える 2

1

アプリをトレースすると、最初にdidChangeSectionが呼び出され、セクション全体が挿入されます。その後、didChangeObjectが繰り返し呼び出されます。

問題は、didChangeSectionでセクション全体を挿入し、テーブルビューが更新される直前に、同じセクションにオブジェクトを追加することです。これは基本的に重複する更新の場合です...(開始/終了更新ブロックでも許可されません)。

個々のオブジェクト挿入をコメントアウトすると、すべて機能します。

 case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

セクションinsert:をコメントアウトすると、機能しません-しかし、insertRowsInSectionsが常に機能することはあまりうまくいきませんでした。これは、セクションがまだないためである可能性があります(これが、挿入した理由であると確信しています)最初のセクション)。適切な粒度で挿入を行うには、どちらの場合も検出する必要がある場合があります。

一般的に、行よりもセクション全体をリロードして挿入する方がはるかに幸運でした。テーブルビューは、作業中の人にとっては非常に厄介なようです。より頻繁に正常に動作するように見えるUITableViewRowAnimationNoneを試すこともできます。

于 2009-10-13T22:35:59.017 に答える
0

私も同じ問題を抱えています。didChangeSectionが2回起動することがわかりました。挿入するオブジェクトを作成するときと、実際に保存するとき。私にとっては、saveが呼び出されるまでdidChangeSectionを呼び出さないでください。または、少なくとも、オブジェクトの作成時にwillChangeSectionが呼び出され、保存時にdidChangeSectionが呼び出されます。

ここで、NSManagedObjectContextDidSaveNotificationオブザーバーメソッドを調べています。これはNSFetchedResultsControllerDelegateプロトコルの一部ではありませんが、登録して受信することができます。おそらく、それは私が実際にsaveを呼び出したときにのみ呼び出され、以前は呼び出されません。

于 2009-12-15T05:22:43.317 に答える