¿Cómo obtener el objeto Core Data de un ID de objeto específico?

120

Puedo obtener fácilmente la identificación de un objeto en Core Data usando el siguiente código:

NSManagedObjectID *moID = [managedObject objectID];

Sin embargo, ¿hay alguna manera de sacar un objeto del almacén de datos principal dándole un ID de objeto específico? Sé que puedo hacer esto usando una NSFetchRequest, como esta:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];

Sin embargo, me gustaría hacerlo de una manera que no inicie su propia solicitud de recuperación. ¿Algunas ideas?

Jason
fuente
Pero con la forma de solicitud de búsqueda, puede establecer propiedades o relaciones para que se recuperen previamente, lo que le brindará una excelente eficiencia en lugar de muchas más consultas a medida que accede a las cosas.
Malhal

Respuestas:

208

Usted quiere:

-(NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID
                                   error:(NSError **)error

Obtiene el objeto de la tienda que tiene ese ID, o nulo si no existe.

(Tenga en cuenta: hay dos métodos en NSManagedObjectContext con nombres similares que me hicieron tropezar. Para ayudar a mantenerlos en orden, esto es lo que hacen los otros dos:

-(NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID

... creará un objeto de error con el ID de objeto proporcionado, ya sea que dicho objeto exista o no en la tienda. Si no existe, cualquier cosa que provoque la falla fallará a menos que inserte el objeto primero con NSManagedObjectContext's insertObject:. El único uso que he encontrado para esto es copiar objetos de una tienda a otra mientras se conservan los ObjectID.

-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID

... devolverá el objeto que tiene ese ID, si ha sido obtenido de la tienda por este managedObjectContext. Si alguien sabe para qué es útil este método, comente).

[eta .: Otra diferencia importante entre el primer método y los otros dos es que existingObjectWithID:error:nunca devuelve una falla; siempre busca todo el objeto. Si está tratando de evitar eso (por ejemplo, trabajando con un objeto costoso de buscar con una propiedad de gran burbuja), debe ser inteligente con objectWithID:o objectRegisteredForID:, que no dispara fallas; o utilice una solicitud de recuperación configurada correctamente.]

rgeorge
fuente
11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDprobablemente sea útil cuando solo desea ver si un objeto ya existe en contexto y no desea recuperarlo.
Tony
Mi situación. En -tableView:didSelectRowAtIndexPath: UIAlertView se muestra sí / no. En "sí", hay algo de trabajo con el objeto. Uso NSFetchedResultsControlleractualizaciones de CoreData en segundo plano desde el control remoto. Entonces no puedo almacenar objetos: mientras la alerta está en la pantalla, el almacenamiento se puede actualizar y eliminar el objeto. Almaceno objectId, luego lo recupero una vez más en alert delegate. Porque yo uso NSFetchedResultsController, todos los objetos necesarios ya están en contexto en este momento. Además, cuando no hay ningún objeto en contexto, CoreData no debería hacer un intento de búsqueda inútil.
kpower
buena respuesta, gracias! estos nombres de métodos son realmente complicados. es fácil estropear todo con el equivocado
chacal
Excelente respuesta, gracias por la aclaración objectWithId:: la necesidad de llamar insertObjectprimero para evitar un aumento de la excepción en el intento de disparar una falla no fue obvia para mí.
Stanislav Pankevich
3
objectRegisteredForID:es útil cuando tiene una lista de objectID de una operación en otro contexto y solo desea actualizar los que pueden tener datos obsoletos en el contexto local. Esto mantiene el gráfico de su objeto (y por lo tanto el uso de la memoria) bajo control, y es mejor que recorrer -registeredObjectsy verificar los ID de objeto para ver si un objeto tiene fallas en su contexto.
Sterling Archer
4

objectWithID:es el método que está buscando y es la forma recomendada de hacerlo. objectWithID:usará de manera eficiente NSManagedObjectContext para extraer el objeto solo en tantos niveles como sea necesario, a diferencia de algunos de los otros medios para hacer esto. objectWithID:utilizará correctamente la información en memoria en contextos principales, el coordinador de almacenamiento persistente y el propio almacén persistente antes de ir al almacenamiento de respaldo.

Esto se trata en profundidad en la sesión de la WWDC 2012 "Mejores prácticas de datos básicos".

sofocar
fuente