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.