2012-03-20 95 views
1

我與膳食和食物有多對多關係(即膳食< < ------ >>食物)。食物是一個抽象類,可以是水果或蔬菜。我有一個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]); 
} 
+1

的溶液可以是在[這個問題]類似於(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 2012-03-20 09:46:29

+0

非常感謝,我想出了錯誤。 – Vikings 2012-03-20 12:24:02

回答

1

顯然我沒有設置fetchedResultsController和上下文爲零。我在dealloc中,但沒有被調用,因爲這是在應用程序委託處聲明的選項卡欄中的一個視圖。所以我簡單地添加了下面的代碼。也許這是因爲我在分享一個背景。

- (void)viewDidDisappear:(BOOL)animated 
{ 
    self.fetchedResultsController = nil; 
    self.context = nil; 
} 
0

是 - 聽起來你沒有添加新的e ntry到NSFetchResultsController支持的NSArray。你做[self.meal addFoodsObject:fruit]之後,你也應該能夠調用類似

[self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath] 
            withRowAnimation: UITableViewRowAnimationRight]; 

自己。 Jeff LaMarche的鏈接是一個很好的解釋。

+0

我沒有看到鏈接 – Vikings 2012-03-20 10:55:46

+0

我指的是@ alan-duncan的鏈接:http://stackoverflow.com/questions/2442865/nsfetchedresultscontroller-is-driving-me-crazy其中有Jeff鏈接裏面爲http ://iphonedevelopment.blogspot.ca/2009/11/i-know-youre-tired-of-hearing-about.html – 2012-03-20 12:05:01

+0

非常感謝,我找到了錯誤。 – Vikings 2012-03-20 12:24:55