Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSInternalInconsistencyException (invalid number of rows)

Whenever I have data in my UITableView and I start deleting, it works fine. However, when I get to the last object in the table, and delete it, it crashes.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'

Here's how I'm doing the editing stuff:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        if ([myData count] >= 1) {
            [tableView beginUpdates];
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [myData removeObjectAtIndex:[indexPath row]];

            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory = [paths objectAtIndex:0];
            NSString *somepath = [documentsDirectory stringByAppendingPathComponent:@"something.plist"];
            [myData writeToFile:somepath atomically:YES];
            [table reloadData];
            if ([myData count] == 0) {
                [tableView endUpdates];
                [tableView reloadData];
            }
            else {
            [tableView endUpdates];
            }
        }
    }   
}

And also this:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    if ([myData count] != 0) {
        return [myData count];
    }
    else {
        return 1;
    }
}

The reason I'm returning 1 is because I'm making a cell that says "No data saved" in cellForRowAtIndexPath. Here's what I mean:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }    
    if ([cityData count] != 0) {
        //normal setup removed for clarity
    }
    else {
        cell.textLabel.text = @"No saved data!";
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14]; 
    cell.textLabel.textAlignment = UITextAlignmentCenter;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.tag = 1;
    return cell;
    }
}

So, what am I doing wrong in my editing code to get this error? Thanks!

like image 318
sudo rm -rf Avatar asked Mar 28 '11 04:03

sudo rm -rf


1 Answers

If you delete the last row in your table, the UITableView code expects there to be 0 rows remaining. It calls your UITableViewDataSource methods to determine how many are left. Since you have a "No data" cell, it returns 1, not 0. So when you delete the last row in your table, try calling -insertRowsAtIndexPaths:withRowAnimation: to insert your "No data" row. Also, you should not call -reloadData anywhere in this method. -endUpdates will take care of reloading the affected rows. Try this out:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        if ([myData count] >= 1) {
            [tableView beginUpdates];
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [myData removeObjectAtIndex:[indexPath row]];

            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory = [paths objectAtIndex:0];
            NSString *somepath = [documentsDirectory stringByAppendingPathComponent:@"something.plist"];
            [myData writeToFile:somepath atomically:YES];

            if ([myData count] == 0) {
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            }
            [tableView endUpdates];
        }
    }   
}
like image 146
Cameron Spickert Avatar answered Sep 19 '22 17:09

Cameron Spickert