Ошибка вставки основных данных - PullRequest
1 голос
/ 20 марта 2012

У меня есть много-много отношений с едой и едой (т.е. еда << ------ >> еда)Еда является абстрагированным классом и может быть фруктом или овощем.У меня есть 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]);
}

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Очевидно, я не устанавливал fetchedResultsController и контекст в ноль. Я был в Deloloc, но это не вызывали, потому что это было одно из представлений в панели вкладок, которое было объявлено в делегате приложения. Поэтому я просто добавил код ниже. Может быть, это потому, что я делюсь контекстом.

- (void)viewDidDisappear:(BOOL)animated
{
    self.fetchedResultsController = nil;
    self.context = nil;
}
0 голосов
/ 20 марта 2012

Да - звучит так, как будто вы не добавили новую запись в NSArray, которой поддерживает NSFetchResultsController.Сразу после того, как вы сделаете [self.meal addFoodsObject:fruit], вы также сможете позвонить себе как

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

.Ссылка Джеффа Ламарша - отличное объяснение.

...