NSInternalInconsistencyException (недопустимое количество строк)

всякий раз, когда у меня есть данные в моем UITableView и я начинаю удалять, он работает нормально. Однако, когда я добираюсь до последнего объекта в таблице и удаляю его, он падает.

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

вот как я делаю редактирование:

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

и так:

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

причина, по которой я возвращаю 1, заключается в том, что я делаю ячейку, которая говорит "нет сохраненных данных" в cellForRowAtIndexPath. Вот что я имею в виду:

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

Итак, что я делаю неправильно в моем редактирование кода для получения этой ошибки? Спасибо!

3 ответов


если вы удалите последнюю строку в таблице, то UITableView код ожидает, что останется 0 строк. Он называет ваш UITableViewDataSource методы, чтобы определить, сколько осталось. Поскольку у вас есть ячейка "нет данных", она возвращает 1, а не 0. Поэтому, когда вы удаляете последнюю строку в своей таблице, попробуйте вызвать -insertRowsAtIndexPaths:withRowAnimation: чтобы вставить строку "нет данных". Кроме того, вы не должны звонить -reloadData в любом месте этого метода. -endUpdates позаботится о перезагрузке затронутых строк. Попробуйте это:

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

сначала удалите из myData, а затем удалите из tableview.

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

if (editingStyle == UITableViewCellEditingStyleDelete) {
        //somehting...
        [myData removeObjectAtIndex:[indexPath row]];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        //somehting...
    }
}   

}


метод tableView:numberOfRowsInSection всегда должно возвращать точное количество строк:

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

после удаления последней строки, вы можете удалить весь раздел. Просто позвоните deleteSections:withRowAnimation: внутри beginUpdates и endUpdated блок;

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [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) {
            // NEW! DELETE SECTION IF NO MORE ROWS!
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade];
        }
        [tableView endUpdates];
    }   
}