Come ottenere l'oggetto Core Data da un ID oggetto specifico?


120

Posso facilmente ottenere l'ID di un oggetto in Core Data utilizzando il codice seguente:

NSManagedObjectID *moID = [managedObject objectID];

Tuttavia, esiste un modo per estrarre un oggetto dall'archivio dati principale assegnandogli un ID oggetto specifico? So che posso farlo usando NSFetchRequest, come questo:

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

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

Tuttavia, mi piacerebbe farlo in un modo che non avvii la propria richiesta di recupero. Qualche idea?


Ma con il modo di richiesta di recupero puoi impostare proprietà o relazioni da precaricare il che ti darà un'eccellente efficienza piuttosto che molte più query mentre accedi alle cose.
malhal

Risposte:


208

Tu vuoi:

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

Recupera l'oggetto dal negozio che ha quell'ID o nullo se non esiste.

(Attenzione: ci sono due metodi su NSManagedObjectContext con nomi che sembrano simili che mi hanno fatto inciampare. Per aiutarti a mantenerli dritti, ecco cosa fanno gli altri due:

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

... creerà un oggetto errore con l'ID oggetto fornito, indipendentemente dal fatto che tale oggetto esista effettivamente o meno nel negozio. Se non esiste, tutto ciò che attiva l'errore fallirà a meno che non si inserisca prima l'oggetto con NSManagedObjectContext's insertObject:. L'unico uso che ho trovato per questo è copiare oggetti da un negozio all'altro preservando gli ObjectID.

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

... restituirà l'oggetto con quell'ID , se è stato recuperato dall'archivio da questo managedObjectContext. Se qualcuno sa a cosa serve questo metodo, per favore commenta.)

[eta .: Un'altra importante differenza tra il primo metodo e gli altri due è che existingObjectWithID:error:non restituisce mai un errore; recupera sempre l'intero oggetto per te. Se stai cercando di evitarlo (ad es. Lavorando con un oggetto costoso da recuperare con una grande proprietà blob), devi essere intelligente con objectWithID:o objectRegisteredForID:, che non genera errori; oppure utilizza una richiesta di recupero configurata correttamente.]


11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDè probabilmente utile quando vuoi solo vedere se un oggetto esiste già nel contesto e non vuoi recuperarlo.
Tony

La mia situazione. Su -tableView:didSelectRowAtIndexPath: UIAlertView con sì / no viene visualizzato. Su "sì" - c'è del lavoro con l'oggetto. Uso NSFetchedResultsController+ aggiornamenti CoreData in background da remoto. Quindi non posso memorizzare oggetti: mentre l'avviso è sullo schermo, la memoria può essere aggiornata e l'oggetto rimosso. Memorizzo objectId, quindi lo recupero ancora una volta in alert delegate. Perché uso NSFetchedResultsController- tutti gli oggetti necessari sono già nel contesto in questo momento. Inoltre, quando non ci sono oggetti nel contesto, CoreData non dovrebbe rendere inutile il tentativo di recupero.
kpower

bella risposta, grazie! questi nomi di metodo sono davvero complicati. è facile rovinare tutto con quello sbagliato
sciacallo

Ottima risposta, grazie per il chiarimento in merito objectWithId:: la necessità di chiamare insertObjectprima per evitare un aumento di eccezione al tentativo di sparare un fallo non mi era evidente.
Stanislav Pankevich

3
objectRegisteredForID:è utile quando si dispone di un elenco di objectID da un'operazione in un altro contesto e si desidera aggiornare solo quelli che potrebbero contenere dati non aggiornati nel contesto locale. Ciò tiene sotto controllo il tuo grafico degli oggetti (e quindi l'utilizzo della memoria), ed è meglio che scorrere -registeredObjectse controllare gli objectID per vedere se un oggetto è difettoso per il tuo contesto.
Sterling Archer

4

objectWithID:è il metodo che stai cercando ed è il modo consigliato per farlo. objectWithID:utilizzerà in modo efficiente NSManagedObjectContext per estrarre l'oggetto solo per il numero di livelli necessario, a differenza di altri mezzi per farlo. objectWithID:utilizzerà correttamente le informazioni in memoria nei contesti padre, il coordinatore dell'archivio persistente e lo stesso archivio persistente prima di passare all'archivio di backup.

Questo argomento è trattato in modo approfondito nella sessione del WWDC 2012 "Core Data Best Practices".


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.