食事と食べ物との関係が多すぎます(つまり、食事< < ------ >>食品)。食べ物は抽象クラスで、果物や野菜のいずれかになります。私は与えられた食事のすべての食品を表示するRootViewControllerを持っています。 1つのクラスでは野菜を追加し、もう1つはフルーツを追加します。コアデータ挿入エラー
これらを食事に追加すると、次のエラーが発生します。私は実際に何が起こっているのか、これがどのように起こっているのかは分かりません。
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1046
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
2012-03-19 22:52:06.652 iGlucoTouch[682:11903] Meal Name: Meal #1 atIndex: 0
RootViewController.h
@interface RootViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate>
{
NSFetchedResultsController *_fetchedResultsController;
NSManagedObjectContext *_context;
UITableView *_tableView;
}
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *context;
@property (nonatomic, retain) UITableView *tableView;
@end
RootViewController.m
@implementation RootViewController
@synthesize fetchedResultsController = _fetchedResultsController;
@synthesize context = _context;
@synthesize tableView = _tableView;
- (void)viewDidAppear:(BOOL)animated
{
self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 400) style:UITableViewStyleGrouped];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.rowHeight = 60.0;
[self.view addSubview:self.tableView];
[self.tableView release];
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
self.context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
Food *food = [_fetchedResultsController objectAtIndexPath:indexPath];
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.meal removeFoodsObject:food];
NSError *error;
if (![self.context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
self.context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
Food *food = [_fetchedResultsController objectAtIndexPath:indexPath];
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.meal removeFoodsObject:food];
NSError *error;
if (![self.context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
}
}
- (NSFetchedResultsController *)fetchedResultsController
{
self.context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Food" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSPredicate *foodPredicate = [NSPredicate predicateWithFormat:@"ANY meals == %@", self.meal];
[fetchRequest setPredicate:foodPredicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
[sort release];
[fetchRequest release];
[theFetchedResultsController release];
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (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];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
私は別のクラスでは、このように果物や野菜を追加します。
はself.context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
Fruit *fruit = [_fetchedResultsController objectAtIndexPath:indexPath];
[self.meal addFoodsObject:fruit];
NSError *error;
if (![self.context save:&error]) {
NSLog(@"Error: %@", [error localizedDescription]);
}
溶液を、[この質問](http://stackoverflow.com/questions/2442865/nsfetchedresultscontroller-is-driving-me-crazy)と同様であってもよいです。私は 'UITableView'のマニュアル(ユーザ主導の)並べ替えを扱うときに、以前はこのエラーに遭遇しました。モデル駆動型の変更とユーザー駆動型の変更を区別するNSFetchedResultsControllerデリゲートメソッドが必要でした。その件に関する[Apple](https://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html)のドキュメント。 – FluffulousChimp
ありがとう、私はエラーを考え出した。 – Vikings