ios - NSPredicate no ejecutado
sqlite core-data (1)
Tuve el mismo problema, esto es lo que descubrí y cómo lo resolví.
Magical Record tiene una raíz NSManagedObjectContext
como padre del NSManagedObjectContext
predeterminado. Cuando creo un NSFetchedResultsController
en el contexto predeterminado, todo parece funcionar bien, igual que usted.
El problema es que todos los nuevos NSManagedObject
regresan con sus ObjectID
''s todavía temporales. Entonces, en mi caso, estaba usando un NSPredicate
para NSPredicate
una consulta en una tabla asociada. No llamé al método de asociación porque no quería cargar todo en la memoria y quería que NSFetchedResultsController
manejara los cambios, para mí.
Con el ObjectID
temporal, la consulta no encuentra resultados y eso es exactamente lo que muestra.
Aparentemente, el contexto secundario (predeterminado) no obtiene el beneficio de la transformación a ID no temporales, aunque se haya conservado en el almacén de respaldo.
Incluso peor maldad sucedió cuando intenté forzar el problema con obtainPermanentIDsForObjects:error:
Core Data se quejó de que no podría satisfacer un error para mi instancia. No importa, no hay manera de que fuera realmente una falla. Simplemente refrescar el objeto tampoco tuvo efecto. Sospecho que este es un error de Core Data que casi nadie hace cosquillas porque solo usan los métodos de asociación para obtener un NSSet.
Mi solución fue usar el contexto padre para NSFetchedResultsController
, al igual que en esta pregunta, Magical Record, saving y NSFetchedResultsController .
Ya estaba envolviendo el valor predeterminado en un nuevo contexto secundario después de la edición y, por lo tanto, copiando las instancias en ese contexto de edición con createInContext
, por lo que no tuve que hacer ningún trabajo adicional más allá de simplemente agregar .parentContext
al argumento.
Por cierto, esto solo sucedió en nuevas instancias de la fuente de la asociación. Una vez que una instancia estaba allí desde el inicio, tenía un ObjectID
no temporal y nunca tuvo el problema.
Esto es bastante divertido. En mi aplicación, creo miles de entradas en la base de datos (en otro hilo, estoy usando MagicalRecord). Todo parece funcionar bien (desde un punto de vista de fondo / primer plano / contexto).
Cuando, en el hilo principal, trato de buscar los datos "recién insertados", descubrí el siguiente comportamiento:
- (NSArray *) familiesInCompany:(Company *) company {
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"company == %@", company];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"company.name == %@", company.name];
NSArray *first = [Family MR_findAllSortedBy:@"name" ascending:YES withPredicate:predicate1];
NSArray *second = [Family MR_findAllSortedBy:@"name" ascending:YES withPredicate:predicate2];
NSArray *third = [Family MR_findByAttribute:@"company" withValue:company andOrderBy:@"name" ascending:YES];
return second;
}
Ahora lo que obtengo es:
- primero: es una matriz vacía
- segundo: contiene todos los objetos de la
Family
, como se esperaba - tercero: es una matriz vacía.
Al depurar la declaración SQL obtengo lo siguiente:
La "primera" declaración:
CoreData: anotación: tiempo total de ejecución de búsqueda: 0.0000s para 0 filas.
La "segunda" declaración ":
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCOMPANY FROM ZFAMILY t0 ÚNETE A ZCOMPANY t1 ON t0.ZCOMPANY = t1.Z_PK ¿DÓNDE t1.ZNAME =? ORDER BY t0.ZNAME
CoreData: anotación: tiempo de recuperación de conexión sql: 0.0005s
CoreData: anotación: tiempo total de ejecución de búsqueda: 0.0007s para 2 filas.
La "tercera" declaración:
CoreData: anotación: tiempo total de ejecución de búsqueda: 0.0000s para 0 filas.
Lo más gracioso es que cierro la aplicación (me refiero a terminarla manualmente) y, y la vuelvo a abrir, funcionan las tres afirmaciones de "captación".
¿Por qué la primera y la tercera declaraciones de búsqueda parecen no ejecutarse nunca? ¿Cómo profundizar en el problema?