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;
}
}
Итак, что я делаю неправильно в своем коде редактирования, чтобы получить эту ошибку? Спасибо!
Ответы
Ответ 1
Если вы удалите последнюю строку в своей таблице, код 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];
}
}
}
Ответ 2
сначала удалите из myData, а затем удалите из таблицы.
-(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...
}
}
}
Ответ 3
Метод 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];
}
}