iPhone アプリで親子 Core Data 関係を設定しています。Manufacturer オブジェクトと Car オブジェクトがあります。これは、メーカーが所有者である対多の関係です。メイン ビューは、メーカーを含むテーブル ビューです。詳細ビューは、さまざまな種類の車を含む別のテーブル ビューです。私はTim Roadley の Core Data Tutorialをベースとして使用しています。このチュートリアルでは、テーブル ビューにStanford の Core Data Table View Libraryを使用します。
車とメーカーを追加しても問題はありませんが、テーブルビューで複数の車を削除すると、次のエラーが発生します。
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037
2012-07-29 23:39:33.561 アプリ [16368:c07] *キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: '無効な更新: セクション 0 の行数が無効です。既存のセクションに含まれる行数更新後 (0) は、更新前にそのセクションに含まれていた行数 (2) に、そのセクションから挿入または削除された行数 (0 挿入、1 削除) をプラスまたはマイナスし、プラスまたはマイナスそのセクションに移動した、またはそのセクションから移動した行数 (移動した行数 0、移動した行数 0)。
唯一の車を削除すると、次のエラーが発生したときに新しい車を追加しようとするまで問題なく動作します。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'manufacturer' between objects in different contexts (source = <Car: 0x6d96da0> (entity: Car; id: 0x6d8a3c0 <x-coredata:///Car/tC78E17EB-1D68-4998-8C4D-6D1199CE253F4> ; data: {
dateAdded = nil;
manufacturer = nil;
carName = new;
}) , destination = <Manufacturer: 0x6bb1f40> (entity: Manufacturer; id: 0x6d87340 <x-coredata://2E8DDF34-B01A-4203-A53E-73DBE6A2F976/Garden/p6> ; data: <fault>))'
これが私の編集方法です:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates];
Plant *plantToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Deleting plant '%@'", plantToDelete.plantName);
[self.managedObjectContext deleteObject:plantToDelete];
[self.managedObjectContext save:nil];
//delete empty tableview row
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
NSLog(@"Before performFetch...");
[self performFetch];
NSLog(@"After performFetch...");
[self.tableView endUpdates];
}
}
このperformFetch
メソッドは、前述のCoreDataTableViewController
ファイルに含まれています。あなたの便宜のために、ここにそれがあります:
(void)performFetch
{
_debug = YES;
if (self.fetchedResultsController) {
if (self.fetchedResultsController.fetchRequest.predicate) {
if (self.debug) NSLog(@"[%@ %@] fetching %@ with predicate: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate);
} else {
if (self.debug) NSLog(@"[%@ %@] fetching all %@ (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName);
}
NSError *error;
[self.fetchedResultsController performFetch:&error];
if (error) NSLog(@"[%@ %@] %@ (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]);
} else {
if (self.debug) NSLog(@"[%@ %@] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
}
[self.tableView reloadData];
}
他の質問によると、私は and を使用してこれを正しく行っていbeginUpdates
ますendUpdates
。これは不可解なエラーです。ご協力いただきありがとうございます。