Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TableView app terminated due to 'NSInternalInconsistencyException'

I'm trying to get the hang of UITableViews and everything that goes with it. At the moment I have the following code:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return 10; 
} 

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

     [cell.textLabel setText:[NSString stringWithFormat:@"I am cell %d", indexPath.row]];

     return cell; 
}

- (IBAction)killItem {
     NSIndexPath *indexToDelete = [NSIndexPath indexPathForRow:2 inSection:0];
     [tbl deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexToDelete] withRowAnimation:UITableViewRowAnimationRight];
}

And I get the following error when initiating the "killItem" function:

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 (10) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'

The way I understand it tableViews basically have a delegate and a data source where the data source, among other things, determines how many rows should be in the tableView. Through some searches here at stackoverflow I've found that this error is caused when the "data source doesn't match reality", when it's searching for rows that don't exist, that I have deleted.

I might have gotten this wrong but that's what I think is doing it. So my question is, how do I get these to match so that I can avoid this error?

For reference, I've looked in to the following posts without understanding what I need to do:

Error : Number of Rows In Section in UITableView in iPhone SDK

Slide UITableViewCell

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

Adding [tbl reloadData], [tbl beginUpdate] ... [tbl endUpdate] in the killItem function, doesen't seem to help my problem eighter.

Thank you in advance, Tobias Tovedal

like image 815
Tobias Tovedal Avatar asked Sep 04 '11 19:09

Tobias Tovedal


2 Answers

Tobias, what you need to do when deleting rows is

// tell the table view you're going to make an update
[tableView beginUpdates];

// update the data object that is supplying data for this table
// ( the object used by tableView:numberOfRowsInSection: )
[dataArray removeObjectAtIndex:indexPath.row];

// tell the table view to delete the row
[tableView deleteRowsAtIndexPaths:indexPath 
           withRowAnimation:UITableViewRowAnimationRight];

// tell the table view that you're done
[tableView endUpdates];


When you call endUpdate the number returned from tableView:numberOfRowsInSection: must be the same as the number at beginUpdate minus the number of rows deleted.

like image 196
Mike Hay Avatar answered Oct 07 '22 06:10

Mike Hay


It's pretty easy, the problem lies here:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 10; 
}

The delegate pattern used by apple, means that you're the one responsible on managing the content of the UITableView through its delegates, meaning that, if you delete a row, you're also responsible of deleting the data from the data model.

So, after deleting a row, it would make sense that the number of rows in section would decrease to "9", yet, your function is always returning 10, and thus throwing the exception.

Typically, when using an table, and the contents will change, an NSMutableArray is pretty common, you do something like this:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [arrayWithStuff count];
}

And then, deleting an object (removeObjectAtIndex:) from the array would automatically update the number of rows.

(Edit: Replied at about the same time as Mike Hay, try following his advice too! I skipped the begin/end Update, because it seems you already read about it)

like image 37
Can Avatar answered Oct 07 '22 05:10

Can