Tengo un UITableView
bastante vainilla administrado por un NSFetchedResultsController
para mostrar todas las instancias de una entidad de datos principal dada.tableView: cellForRowAtIndexPath llamado con nil indexPath después de eliminar el elemento
Cuando el usuario elimina una entrada en la vista de tabla al golpear sobre ella, tableView:cellForRowAtIndexPath:
finalmente es llamado en mi UITableViewController
con un nil
indexPath
. Dado que no esperaba que se llamara con un nil
indexPath
, la aplicación se bloquea.
Puedo solucionar el problema comprobando el valor nil
y luego devolver una celda vacía. Esto parece funcionar, pero aún me preocupa que haya manejado algo mal. ¿Algunas ideas? ¿Alguien ha visto alguna vez tableView:cellForRowAtIndexPath:
llamado con un nil
indexPath
?
Tenga en cuenta que esto solo ocurre cuando el usuario elimina de la vista de tabla deslizando sobre la celda. Al eliminar un elemento utilizando el modo de edición de vista de tabla, no sucede. ¿Cuál sería la diferencia entre las dos formas de eliminar una celda?
Entonces, ¿es realmente una situación correcta obtener nil
indexPath
en un método delegado de vista de tabla?
Mi código de controlador de vista es realmente estándar. Aquí es la supresión:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.moc deleteObject:managedObject];
NSError *error = NULL;
Boolean success = [self.moc save:&error];
if (!success) { <snip> }
// actual row deletion from table view will be handle from Fetched Result Controller delegate
// [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else { <snip> }
}
Esto conducirá al método NSFetchedResultsController
delegado siendo llamados:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeInsert: <snip> break;
case NSFetchedResultsChangeUpdate: <snip> break;
case NSFetchedResultsChangeMove: <snip> break;
}
}
Y, por supuesto, los métodos de fuente de datos son manejados por el NSFetchedResultsController
, por ejemplo:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
Muchas gracias.
¿Ha verificado todos estos serán llamadas en el orden predicho? – Mundi
Intenta llamar 'reloadData' en tu vista de tabla en' tableView: commitEditingStyle: forRowAtIndexPath' inmediatamente * después * de guardar los cambios en el contexto del objeto administrado. Tuve un problema similar con esto y volver a cargar la vista de tabla lo solucionó. – Greg