Exc_bad_access - nsfetchedResultScontroller, uableViewController, uinavigationController, uipopoverController
-
27-10-2019 - |
Pregunta
tengo un UITableViewController
dentro de una UINavigationController
, dentro de una UIPopoverController
.
los UITableViewController
usa un NSFetchedResultsController
. didselectrowatIndexpath empuja otra instancia de mi UITableViewController
con un ligeramente diferente Predicar en la pila del controlador NAV.
Si presiono un nuevo UITableViewController
En la pila, y luego lo haz de nuevo, eventualmente obtendré un EXC_BAD_ACCESS
Si trato de guardar un objeto que hubiera actualizado el TableView que se apareció.
Como se esperaba, establecer el delegado de mi NSFetchedResultsController
a nil
elimina el EXC_BAD_ACCESS
errores.
Estoy usando arco. Claramente, estos objetos se están lanzando. Esto esta bien. Pero, ¿por qué todavía se les notifica cuando hay un cambio?
Código a continuación. Básicamente estoy rastreando la historia de una vista web en mi base de datos.
BookmarkViewController * bookmarkController = [[BookmarkViewController alloc] initWithStyle:UITableViewStylePlain andWebView:self.webView];
UINavigationController * bookmarkNavController = [[UINavigationController alloc] initWithRootViewController:bookmarkController];
self.bookmarkPopover = [[UIPopoverController alloc] initWithContentViewController:bookmarkNavController];
_bookmarkPopover.popoverContentSize = CGSizeMake(320, 44*10);
_bookmarkPopover.delegate = self;
bookmarkController.container=_bookmarkPopover;
bookmarkController.delegate=self;
los BookmarkViewController
usa un NSFetchedResultsController
y BookmarkViewController
es el delegate
del NSFetchedResultsController
.
- (NSFetchedResultsController *) myFetchedResultsController
{
if (self.fetchedResultsController != nil) {
return self.fetchedResultsController;
}
// Singleton
CoreDataManager * dataManager = [CoreDataManager defaultDataManager];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bookmark" inManagedObjectContext:dataManager.managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"label" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:self.predicate];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20]; // Set the batch size to a suitable number.
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:dataManager.managedObjectContext
sectionNameKeyPath:@"type"
cacheName:nil];
self.fetchedResultsController.delegate = self;
return self.fetchedResultsController;
}
Y también tengo:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BookmarkViewController * bookmarkViewController = [[BookmarkViewController alloc] initWithStyle:self.tableView.style
andWebView:self.webview
forFolder:bookmark.label];
[self.navigationController pushViewController:bookmarkViewController animated:YES];
}
Solución
Encontré algunas preguntas relacionadas:
Si lento, obtengo un mal acceso, si conservo, me filtro
El segundo enlace me dio la idea de establecer al delegado en nulo en el método de DealLoc
-(void) dealloc
{
self.fetchedResultsController.delegate = nil;
}
Pero estoy usando arco, así que no puedo llamar [super dealloc]
explícitamente. Parece solucionar el problema, pero no estoy seguro de que esto sea correcto. ¿Debería establecer el resto de mis variables locales a nil
? Si esto anula lo que genera el compilador, ¿se filtrará?