5

テーブル ビューを使用してコア データからアイテムのリストを表示するアプリがあります。リモート API を使用しており、テーブル ビューをプルダウンした後にコンテンツを更新しています。これにより、API の呼び出しがトリガーされます。

データが取得、解析され、コア データに挿入/更新されます。

Core Data コンテキストを保存した後にエラーが発生することがあります...これには複数のスレッドを使用していないことに注意してください。

私は文字通りかなり怒っています。この男にも同様の問題があるようですが、彼の解決策で私の問題を解決することはまだできません 。NSFetchedResultsController のデリゲートからキャッチされた例外

完全なエラーは次のとおりです。

2012-07-31 14:14:47.332 MyApp[2893:11303] 
*** Assertion failure in -[_UITableViewUpdateSupport _setupAnimationsForNewlyInsertedCells], 
/SourceCache/UIKit_Sim/UIKit-1914.84/UITableViewSupport.m:1133
2012-07-31 14:14:47.332 MyApp[2893:11303] CoreData: error: Serious application error.  
An exception was caught from the delegate of NSFetchedResultsController during a call to -
controllerDidChangeContent:.  
Attempt to create two animations for cell with userInfo (null)

更新

フェッチ要求に述語があります。API から以前にダウンロードされ、新しい JSON 結果から欠落しているオブジェクトを削除しているように見えるため。hideFromUser フラグを設定しています。これは Core Data に保存されます。

このフラグが YES の場合、テーブル ビューには表示されません。でも大丈夫なら大丈夫です。また、何か変更があった場合に備えて、その管理対象オブジェクトに関する情報も更新しています。以前は非表示に設定されていたオブジェクトがあり、現在は表示に設定されており、新しいデータもいくつかある可能性はありますか?

それについて考えるほど、関連性があるとは思えません。

データを更新する方法は次のとおりです。

1) 対応するタイプのすべての関連オブジェクトを「フォーム ユーザーを非表示」に設定しました (NSPredicate により、テーブル ビューに表示されなくなります)。

2) JSON データから NSArray を取得します。

3) 各項目をループし、私の createABookOfClass:withJSON: メソッドは、(json ディクショナリの ID を使用して) 本のコア データをクエリします。見つからない場合は、新しい本を作成します。注: この時点で、「ユーザー フラグから非表示」は元に戻されます。

4) すべての作業が完了したら、保存します。

[[DPLocalStore getInstance] hideFlagItemsOfType:NSStringFromClass([MyFavouriteBook class])];

NSArray * itemsJSON = [data mutableObjectFromJSONData];

[itemsJSON enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {     
    [[DPLocalStore getInstance] createABookOfClass:[MyFavouriteBook class]
                                          withJSON:obj];
}];

NSError *error = nil;
BOOL didsave = [[DPLocalStore getInstance] save:&error];

オブジェクト A を含むセルが更新された可能性があります。これは更新です。非表示フラグが変更されました。したがって、NSFetchedResultsControllerのデリゲートがそのセルを更新し、それも削除したい状況に陥っています...述語がこのオブジェクトに対応していないため...その可能性は非常に高いです...

4

1 に答える 1

10

エラーを見つけたのかもしれませんが、変更したので問題は発生していないので、問題ないと思います。

私の実装ではcontroller:didChangeObject:atIndexPath:forChangeType:newIndexPath:、次のスイッチステートメントにこれがありましたNSFetchedResultsChangeMove

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

    // Reloading the section inserts a new row and ensures that titles are updated appropriately.
    [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section]
             withRowAnimation:UITableViewRowAnimationFade];
    break;

これは古いプロジェクト (私は参加していません) で使用されていたので、controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:実装全体は問題ないと思いました。

その結果、私は Apple 開発者サイトでもう一度それについて読むまで、あまり注意を払いませんでした。NSFetchedResultsChangeMoveそして、セルを削除し、新しいパスにセルを挿入する必要があることに気付きました。しかし、私は本当に気づかずに実装していました - セルを削除して、セクションをリロードしてください!

実際には、次のものが必要であり、現在は次のとおりです。

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

私が言ったように、それ以来問題はありませんでした。内部の仕組みがこれに関与していることを誰からも知りたいです-例外は「セルの2つのアニメーションを作成しようとする」ことでした.

ご関心をお寄せいただきありがとうございます。

于 2012-08-01T18:04:00.300 に答える