#iphone #objective-c #uitableview
#iPhone #objective-c #uitableview
Вопрос:
Когда я удаляю ячейку из своей таблицы, я получаю следующую ошибку:
Ошибка утверждения в -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim /UIKit-1448.89 /UITableView.m:995 Серьезная ошибка приложения. Исключение было получено от делегата NSFetchedResultsController во время вызова -controllerDidChangeContent :. Недопустимое обновление: недопустимое количество строк в разделе 0. Количество строк, содержащихся в существующем разделе после обновления (5), должно быть равно количеству строк, содержащихся в этом разделе до обновления (5), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставлено, 1 удалено). с помощью userInfo (null)
Вот соответствующий код:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the managed object for the given index path
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
NSLog(@"fetched results : n%@n",[self.fetchedResultsController fetchedObjects]);
// Commit the change.
NSError *error = nil;
// Update the array and table view.
if (![managedObjectContext save:amp;error])
{
// Handle the error.
}
//[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
#pragma mark - Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.resultsTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.resultsTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.resultsTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.resultsTableView;
switch(type)
{
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.resultsTableView endUpdates];
}
Я попытался удалить [self.setsTableView reloadData];
из последнего метода, но это тоже не сработало.
Ответ №1:
похоже, что вы удаляете ячейку из таблицы, но не удаляете объект из источника данных таблицы, что создает несоответствие. попробуйте добавить что-то вроде:
[[[self.fetchedResultsController sections] objectAtIndex:indexPath.section] removeObjectAtIndex:indexPath.row];
когда вы используете tableView:deleteRowsAtIndexes
число, возвращаемое numberOfRowsInSection:
, должно совпадать с количеством строк в вашем TableView, минус / плюс те, которые вы удалили / добавили
Ответ №2:
Измените себя.fetchedResultsController в fetchedResultsController всеми вышеперечисленными способами. Просто сохраняйте self.fetchedResultsController только в методе
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
//—Попробуйте сохранить managedObjectContext в качестве переменной-члена и используйте следующий метод установки //.
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext != nil)
{
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext;
}
Комментарии:
1. Спасибо, я попробую это, но у меня даже нет метода numberOfSectionsInTableView. Вы имеете в виду numberOfRowsInSection?
2. НЕТ, я имею в виду только numberOfSectionsInTableView. Можете ли вы заархивировать и отправить .h и .m файл вашего viewcontroller?
3. Спасибо, Адарш. Я заархивировал и связал файлы .h и .m здесь: box.net/shared/static/9gaqho979f.zip
4. Спасибо, Adarsh, так что мне следует удалить
self.managedObjectContext = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
из-viewDidLoad
и вызвать вместо этого указанный вами метод?5. да, спасибо, но я думал, что должен делать только
NSPersistentStoreCoordinator *coordinator
в делегате приложения?