문제

I have problem with saving data to CoreData and displaying on table view controller.The problem is on this video: https://www.youtube.com/watch?v=6Di9zeAeBWs&feature=youtu.be

When I delete class doesn't occur any problem. The class is deleted correctly.(part1 of my video). But when I add a new class the program reports a error:

2014-03-13 16:31:02.771 IISForTeachers[30568:70b] 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 (3) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 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) 2014-03-13 16:31:02.774 IISForTeachers[30568:70b] _context SAVED changes to persistent store.

After the error are date saved to persistent store. The save of data works properly, because I see the new clas in table view controller and when I stop and run the app again, the new data are there. But when I add a new class and than I want delete a class, app crash (part 2 of video).

When I run the app again, new class is in table view and I delete it without problem (part 3).

Here is my code of function for deleting a cell:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if(debug == 1){
        NSLog(@"Running %@ '%@'",self.class, NSStringFromSelector(_cmd));
    }

    CoreDataHelper *cdh = [(AppDelegate *) [[UIApplication sharedApplication] delegate] cdh];

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        SchoolClass *class = [self.frc objectAtIndexPath:indexPath];
        [[class managedObjectContext] deleteObject:class];
    }

    [cdh saveContext];

    [self.tableView reloadData];
}

FRC

Fetching date in ClassesTVC.m (table view controller, where are display all classes).

-(void)configureFetch{
    if(debug == 1){
        NSLog(@"Running %@ '%@'",self.class, NSStringFromSelector(_cmd));
    }

    CoreDataHelper *cdh = [(AppDelegate *) [[UIApplication sharedApplication] delegate] cdh];

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];

    request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES], nil];

    [request setFetchBatchSize:50];

    self.frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                   managedObjectContext:cdh.context
                                                     sectionNameKeyPath:nil
                                                              cacheName:nil];
    self.frc.delegate = self;

}

The frc is definet in CoreDataTVC.h (universal class for work with table view controller) and is defined as fallows:

@property (strong, nonatomic) NSFetchedResultsController *frc;

There (CoreDataTVC) is also a function performFetch:

-(void)performFetch{

    if(debug == 1){
        NSLog(@"Running %@ '%@'",self.class, NSStringFromSelector(_cmd));
    }
    if(self.frc){
        [self.frc.managedObjectContext performBlock:^{
            NSError *error = nil;
            if(![self.frc performFetch:&error]){
                NSLog(@"Failed to perform fetch: %@", error);
            }
            [self.tableView reloadData];
        }];
    }
    else{
        NSLog(@"Failed to fetch, the fetched results controller is nil.");
    }
}

EDIT -----------

I change my code and now the function for deleting row is as follows:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if(debug == 1){
        NSLog(@"Running %@ '%@'",self.class, NSStringFromSelector(_cmd));
    }

    CoreDataHelper *cdh = [(AppDelegate *) [[UIApplication sharedApplication] delegate] cdh];

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [tableView beginUpdates];
        SchoolClass *class = [self.frc objectAtIndexPath:indexPath];
        [[class managedObjectContext] deleteObject:class];
        [tableView endUpdates];
    }

    [cdh saveContext];

    [self.tableView reloadData];
}

Now the app works good, but only when I insert one input (classname). When I insert class name and classteacher is empty, than I can delete the cell with any problems. But when I insert both inputs (classname, classteacher) the app is displaying again the error. Here is application behaviour sorry for the quality of video: https://www.youtube.com/watch?v=PqSxqjuyZbU&feature=youtu.be

Error is same:

2014-03-14 12:15:08.309 IISForTeachers[35735:70b] 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 (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 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)

Here is code of assign texfield to object class type. I don't know where could be problem. Thanks for help.

-(void)textFieldDidEndEditing:(UITextField *)textField{
    if (debug == 1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }

    CoreDataHelper *cdh = [(AppDelegate *)[[UIApplication sharedApplication]delegate]cdh];

    SchoolClass *class = (SchoolClass*) [cdh.context existingObjectWithID:self.selectedClassID error:nil];

    if(textField == self.classNameTextField){
        if([self.classNameTextField.text isEqualToString:@""])
        {
            self.classNameTextField.text = @"Nova trida";
        }
        class.name = self.classNameTextField.text;
    }
    else if (textField == self.classTeacherTextField){
        class.classTeacher = self.classTeacherTextField.text;
    }
}
도움이 되었습니까?

해결책

Update your views appropriately when deleting cells, the error tells you exactly what the UITableView expects.

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if(debug == 1){
        NSLog(@"Running %@ '%@'",self.class, NSStringFromSelector(_cmd));
    }

    CoreDataHelper *cdh = [(AppDelegate *) [[UIApplication sharedApplication] delegate] cdh];

    if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
        SchoolClass *class = [self.frc objectAtIndexPath:indexPath];
        [[class managedObjectContext] deleteObject:class];

        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [cdh saveContext];
        [tableView endUpdates];
    }



}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top