32

Estoy escribiendo una aplicación con dos tablas en una pantalla. La tabla de la izquierda es una lista de carpetas y la tabla de la derecha muestra una lista de archivos. Al tocar en una fila a la izquierda, la tabla derecha mostrará los archivos que pertenecen a esa carpeta.NSFetchedResultsController: cambio de predicado no funciona?

Estoy utilizando Core Data para el almacenamiento. Cuando la selección de la carpeta cambie, el predicado de búsqueda del NSFetchedResultsController de la tabla correcta cambiará y realizará una nueva búsqueda, luego volverá a cargar los datos de la tabla. He utilizado el siguiente fragmento de código:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"list = %@",self.list]; 
[fetchedResultsController.fetchRequest setPredicate:predicate]; 
NSError *error = nil; 
if (![[self fetchedResultsController] performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 
[table reloadData]; 

Sin embargo, los resultados de la exploración siguen siendo los mismos. Tengo NSLog'ed "predicado" antes y después de la búsqueda, y estaban correctos con la información actualizada. Los resultados de búsqueda permanecen igual que la búsqueda inicial (cuando se carga la vista).

No estoy muy familiarizado con la forma en que Core Data recupera objetos (¿hay un sistema de almacenamiento en caché?), Pero he hecho cosas similares antes (cambio de predicados, recuperación de datos y actualización de tabla) puntos de vista y todo fue bien.

Si alguien pudiera darme una pista, sería muy apreciado.

Gracias de antemano.

Respuesta

55

que tenían casi exactamente este problema, hasta que encontré la pista en un blog muy reciente en iphone incubator

NSFetchedResultsController es el almacenamiento en caché los primeros resultados. (Probablemente tiene algo configurado en initWithFetchRequest: managedObjectContext: sectionNameKeyPath: cacheName)

Supongo que su código (como el mío) es una derivación del ejemplo de CoreData, suponiendo que es @ "Root", antes de cambiar el predicado , hacer un

[NSFetchedResultsController deleteCacheWithName:@"Root"]; 
+0

Funcionó. ¡Gracias! –

+0

Gracias, eso solucionó mi problema también. Aunque no obtuve los mismos resultados, tuve un bloqueo en iOS 3.2/4.0. ¡Funcionó bien en 3.1 aunque! –

+1

Tenga en cuenta que la memoria caché de entidades se conserva _a través de la aplicación runs_. Tuve un momento muy confuso tratando de descubrir por qué cambiar el predicado en sí mismo en el código fuente no tuvo ningún efecto al reconstruir y ejecutar la aplicación. Apple dice lo siguiente: "Si encuentra un caché con el mismo nombre, el controlador prueba el caché para determinar si su contenido sigue siendo válido. El controlador compara el nombre de la entidad actual, el hash de la versión de la entidad, los descriptores de orden y la ruta clave de la sección con los almacenados en el caché ". Tenga en cuenta que el predicado ** no está incluido ** en esa lista. – aroth

1

En mi caso la respuesta de deafgreatdane no está funcionando; lo que hice en cambio, es probable que ingenuo, pero funciona:

  • crear predicado correspondiente (s) en el configureCell:atIndexPath: método (denominado en tableView:cellForRowAtIndexPath:)
  • luego llamar a:
    [_fetchedResultsController.fetchRequest setPredicate:predicate];
    [_fetchedResultsController performFetch:nil];
  • se refieren para el objeto devuelto llamando al [self.fetchedResultsController objectAtIndexPath:indexPath]
1

Esto funcionó para mí:

[NSFetchedResultsController deleteCacheWithName:nil]; 
[self.fetchedResultsController.fetchRequest setPredicate:predicate]; 

NSError *error = nil; 
if (![self.fetchedResultsController performFetch:&error]) { 
    NSLog(@"%@, %@", error, [error userInfo]); 
    abort(); 
} 
Cuestiones relacionadas