davidOhara
davidOhara

Reputation: 1008

Delete a Row from UITableView causes Crash

following situation: i want to delete a row from my UITableView, but this always crashes...

@property (nonatomic,retain) NSMutableArray *daten;

@synthesize daten;

then in my viewDidLoad i fill my Array:

-(NSMutableArray *) daten{
if (!daten) {
    self.daten = [[NSMutableArray alloc] init];
}

@try {
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSString *dbPath = [self getDBPath];
    BOOL success = [fileMgr fileExistsAtPath:dbPath];
    if(!success)
    {
        NSLog(@"Cannot locate database file '%@'.", dbPath);
    }
    if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
    {
        NSLog(@"An error has occured: %s", sqlite3_errmsg(db));

    }


    const char *sql = "SELECT * FROM  Daten";
    if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
    {
        NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(db));
    }else{

        while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
            Daten * infos = [[Daten alloc] init];
            infos.download = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
            infos.upload = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
            infos.ping = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,3)];
            infos.comment = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,4)];
            infos.date = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,5)];
            infos.type = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,6)];
            infos.lati = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,7)];
            infos.longi = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,8)];


            [daten addObject:infos];
        }
    }
}
@catch (NSException *exception) {
    NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(db));
}
@finally {
    sqlite3_finalize(sqlStatement);
    sqlite3_close(db);

    return daten;
}
}

if i want to delete a row:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the data source
    //[self.daten removeAllObjects];
    NSString *selectedCategory = [self.daten objectAtIndex:indexPath.row];
    NSLog(@"there are %d objects in the array", [self.daten count]);
    [self.daten removeObjectAtIndex:indexPath.row]; //we assume, that mySourceArray is a NSMutableArray we use as our data source
    NSLog(@"there are %d objects in the array", [self.daten count]);

    [self.tableView beginUpdates];

    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    [self.tableView endUpdates];

....}

it crashes because my Array Count is before and after deleting the same! But i don´t know why...

my NumberOfRowsInSection:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

// Return the number of rows in the section.
return [self.daten count];


}

Here´s the Exception:

2012-10-15 16:45:13.778 Speedcheck[5297:907] *** Assertion failure in -[UITableView         _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2372/UITableView.m:1070

2012-10-15 16:45:13.779 Speedcheck[5297:907] * 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 (26) must be equal to the number of rows contained in that section before the update (26), 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).' * First throw call stack: (0x3adcf3e7 0x35934963 0x3adcf29d 0x390c67b3 0x36569ba1 0x82311 0x366fefe1 0x3662003f 0x3661fff3 0x3661ffcd 0x3661f883 0x3662003f 0x3661fff3 0x3661ffcd 0x3661f883 0x3661fd71 0x365485c1 0x365358a9 0x365351b7 0x3ac025f7 0x3ac02227 0x3ada43e7 0x3ada438b 0x3ada320f 0x3ad1623d 0x3ad160c9 0x3ac0133b 0x36589289 0x51d33 0x34984b20) libc++abi.dylib: terminate called throwing an exception

Upvotes: 1

Views: 508

Answers (4)

sosborn
sosborn

Reputation: 14694

You almost have it. What you really want to do thought is put this line right after you check the editing style:

if (editingStyle == UITableViewCellEditingStyleDelete) {

[self.tableView beginUpdates];

This is because you want the model changes to take place in the beginUpdates block, otherwise you get that inconsistency.

Upvotes: 0

Abdullah Umer
Abdullah Umer

Reputation: 4644

The easiest way to remove cell from UITableView is to remove the object from data array.

Just do the following:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        NSInteger rowNumber = indexPath.row;

        [self.daten removeObjectAtIndex:rowNumber];

        [tableView reloadData];
    }
}

Upvotes: 0

Eiko
Eiko

Reputation: 25632

It seems problem is your -(NSMutableArray *) daten method.

It looks like you want to do lazy initialization, but in fact, whenever this method is called, the array is reconstructed again. So your deletion is only valid until the array is accessed the next time, when the array is filled up again (even looks as if it should grow and grow).

You might want to have something like

-(NSMutableArray *) daten{
   if (daten)
      return daten;

   self.daten = [[NSMutableArray alloc] init];

   // ... same setup as before

}

instead.

Upvotes: 3

Nenad M
Nenad M

Reputation: 3055

I don't know if it helps, because it wouldn't make sense to me, but put the [self.daten removeObjectAtIndex:indexPath.row]; just after the call to [self.tableView beginUpdates]; and report the result to us!

Upvotes: 1

Related Questions