2010-10-13 12 views
25

que estoy presentando la vista tabla contenidos utilizando NSFetchedResultsController que tiene un predicado:NSFetchedResultsController con predicado ignora los cambios se fusionaron a partir de diferentes NSManagedObjectContext

[NSPredicate predicateWithFormat:@"visible == %@", [NSNumber numberWithBool:YES]] 

El subproceso de fondo usando separada NSManagedObjectContext puedo actualizar algunas de las entidades y cambiar el suyo valor visible de NO a YES. Guarde, fusione cambios en el hilo principal NSManagedObjectContext. Pero NSFetchedResultsController 's fetchedObjects no cambia. Además, el controlador no llama al -controller:didChangeObject:... en el delegado. Si las entidades se actualizan en el hilo principal de la misma manera (mi aplicación de prueba llama al mismo método), todo funciona como se espera.

También la notificación NSUpdatedObjectsKey contiene esos objetos.

Actualmente las únicas soluciones que he encontrado es que llamar para cada una de las entidades NSUpdatedObjectsKey:

NSManagedObjectContext *context = ... // main thread context 
[context existingObjectWithID:[object objectID] error:nil] 

Este problema es sólo con la actualizados objetos que antes no coinciden con el predicado.

¿Me falta algo obvio?

+0

¿No es un error de Core Data? Creo que deberíamos enviar un informe de errores a Apple. Solo hice uno. – an0

+0

¿Error? Si es así, ¿hay algún progreso? – lostintranslation

+0

Este error finalmente se solucionó en iOS 10: https://twitter.com/an0/status/750413478620491776 – an0

Respuesta

53

Desactiva el evento NSManagedObjectContext no provocó el incendio NSManagedObjectContextObjectsDidChangeNotification para los objetos actualizados porque no está hecho para objetos con errores.

solución genérica (o mantener un registro de ID de objetos que necesita este tratamiento):

NSManagedObjectContext *context = [self managedObjectContext]; 
for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) { 
    [[context objectWithID:[object objectID]] willAccessValueForKey:nil]; 
} 

[context mergeChangesFromContextDidSaveNotification:notification]; 

De NSManagedObject Class Reference:

Puede invocar este método con el valor de clave de cero a garantizar que se ha disparado una falla , como se ilustra en con el siguiente ejemplo.

+0

Esto me ahorró mucho tiempo. No puedo votar esto lo suficiente. Gracias. –

+0

Wow lo mismo para mí. He estado perdiendo horas en esto! – samvermette

+0

¿No debería haber una forma de hacer esto con diferentes configuraciones en 'NSFetchRequest'? Intenté especificar 'relationshipsForPrefetching' y - [NSFetchRequest setReturnsObjectAsFaults: NO]', pero ninguno funcionó. –

2

usted tiene que llamar processPendingChanges en su fondo NSManagedObjectContext después incorporaron los cambios con respecto a otro NSManagedObjectContext.

consulta la Guía de Programación CoreData:

Tenga en cuenta que la notificación de cambio se envía en el método processPendingChanges de NSManagedObjectContext. El hilo principal está vinculado al ciclo del evento para que processPendingChanges se invoque automáticamente después de cada evento de usuario en contextos propiedad del subproceso principal . Este no es el caso para los subprocesos en segundo plano: cuando el método es invocado depende tanto de la plataforma como de la versión de lanzamiento, por lo que no debe depender de un tiempo en particular. Si el contexto secundario no es en el hilo principal, debe llamar a processPendingChanges usted mismo al coyunturas apropiadas.

+0

¿Estás seguro de que esto solucionaría el problema anterior? No creo que el controlador NSFetchedResults esté escuchando notificaciones de cambio del contexto * background *. –

+0

'mergeChangesFromContextDidSaveNotification:' realiza (casi) el mismo proceso que 'processPendingChanges', y publica la notificación correspondiente. – quellish

Cuestiones relacionadas