Kex
Kex

Reputation: 8629

UITableView using deleteRowsAtIndexPaths but crashing app if new row created (vie a message being received)

in my app I have a UITableView containing messages. Each row is one message. When I delete a message, I first delete it from the messages array and then use deleteRowsAtIndexPaths:

    int index =  (int)[self.messages indexOfObject:message];
    [self.messages removeObject:message];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
    NSArray *indexes = [[NSArray alloc] initWithObjects:indexPath, nil];

    [self.tableView deleteRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationLeft];

This works fine however when a new message is received, the push notification triggers the table refresh. Sometimes a new message will be placed in the array just before deleteRowsAtIndexPaths finishes executing and hence the app crashes because the number of rows in the table after the method completes does not equal the number of rows before minus the number of deleted rows. Example error message:

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 (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).'

Has anyone come across a problem like this before? Is there another approach or workaround I can take to stop the app crashing like this?

Any pointers would be great

Upvotes: 0

Views: 117

Answers (1)

Doro
Doro

Reputation: 2413

I had the same kind of issue. And what i did:

  1. declare activity flag for you update:

    @property (nonatomic, assign) BOOL canEdit;

  2. insert self.canEdit = NO when your perform some update operation

  3. override willDisplayCell and check, if there will display last cell of your tableview's datasource array (so, update will end after that cell)

    -(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath  
    { 
    
    if ([dataArray count]- 1 == indexPath.row && self.canEdit == NO)  
                    self.canEdit = YES;}
    
  4. When you receive push notification - check this flag, and if it's YES - perform update. If no - request update after some time

Upvotes: 1

Related Questions