核心数据插入错误 [英] Core Data Insertion Error

查看:134
本文介绍了核心数据插入错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与膳食和食物有一对多的关系(即Meal<< - > Food)。食物是一个抽象的类,可以是水果或蔬菜。我有一个RootViewController显示所有的食物在给定的膳食。在一个类中,我添加了一个蔬菜,另一个我添加了一个水果。

I have a to-many relationship with Meals and Food (i.e. Meal <<------>> Food). Food is an abstracted class, and can be either a Fruit or Vegetable. I have a RootViewController that displays all the Food in a given Meal. In one class I add a Vegetable and another I add a Fruit.

当我开始添加这些到一个膳食时,得到以下错误。

I get the following error when I start adding these to a Meal. I am really not sure what is going on and how this is happening.

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

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

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];
}

我在另一个类中添加了一个水果或蔬菜:

I add a Fruit or Vegetable like this in another class:

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]);
}


推荐答案

显然我没有设置fetchedResultsController和上下文为nil。我在dealloc,但是没有得到调用,因为这是在应用程序委托声明的选项卡栏中的视图之一。所以我只是添加了下面的代码。也许是因为我正在分享一个上下文。

Apparently I was not setting the fetchedResultsController and the context to nil. I was in the dealloc, but that was not getting called because this was one of the views in a tab bar which was declared at the application delegate. So I simply added the code below. Maybe it is because I am sharing a context.

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

这篇关于核心数据插入错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆