식사와 음식과의 관계가 많습니다 (예 : 식사 < < ------ >> 음식). 음식은 추상적 인 수업이며, 과일이나 야채 일 수 있습니다. 주어진 식사의 모든 음식을 표시하는 RootViewController가 있습니다. 한 클래스에서는 야채를 추가하고 다른 하나는 과일을 추가합니다.핵심 데이터 삽입 오류
식사에 추가하기 시작하면 다음과 같은 오류가 발생합니다. 나는 무슨 일이 일어나고 있는지 그리고 어떻게 일어나고 있는지 잘 모르겠습니다.
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