Wie erhalte ich ein Core Data-Objekt von einer bestimmten Objekt-ID?

120

Mit dem folgenden Code kann ich die ID eines Objekts in Core Data problemlos abrufen:

NSManagedObjectID *moID = [managedObject objectID];

Gibt es jedoch eine Möglichkeit, ein Objekt aus dem Kerndatenspeicher zu entfernen, indem Sie ihm eine bestimmte Objekt-ID geben? Ich weiß, dass ich dies mit einem NSFetchRequest wie folgt tun kann:

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

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

Ich möchte dies jedoch so tun, dass keine eigene Abrufanforderung initiiert wird. Irgendwelche Ideen?

Jason
quelle
Mit der Methode zum Abrufen von Anforderungen können Sie jedoch festlegen, dass Eigenschaften oder Beziehungen vorab abgerufen werden, wodurch Sie beim Zugriff auf bestimmte Elemente eine hervorragende Effizienz erzielen und nicht viel mehr Abfragen.
Malhal

Antworten:

208

Sie wollen:

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

Ruft das Objekt aus dem Geschäft mit dieser ID ab oder null, wenn es nicht vorhanden ist.

(Beachten Sie: Es gibt zwei Methoden in NSManagedObjectContext mit ähnlich aussehenden Namen, die mich ausgelöst haben. Um sie gerade zu halten, tun die beiden anderen Folgendes:

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

... erstellt ein Fehlerobjekt mit der angegebenen Objekt-ID, unabhängig davon, ob ein solches Objekt tatsächlich im Geschäft vorhanden ist oder nicht . Wenn es nicht vorhanden ist, schlägt alles fehl, was den Fehler auslöst, es sei denn, Sie fügen das Objekt zuerst mit NSManagedObjectContext ein insertObject:. Die einzige Verwendung, die ich dafür gefunden habe, ist das Kopieren von Objekten von Geschäft zu Geschäft unter Beibehaltung von ObjectIDs.

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

... gibt das Objekt mit dieser ID zurück, wenn es von diesem verwalteten Objekttext aus dem Speicher abgerufen wurde. Wenn jemand weiß, wofür diese Methode nützlich ist, kommentieren Sie bitte.)

[eta.: Ein weiterer wichtiger Unterschied zwischen der ersten und den beiden anderen Methoden besteht darin, dass existingObjectWithID:error:niemals ein Fehler zurückgegeben wird. es holt immer das ganze Objekt für Sie. Wenn Sie versuchen, dies zu vermeiden (z. B. mit einem teuer zu beschaffenden Objekt mit einer großen Blob-Eigenschaft zu arbeiten), müssen Sie mit objectWithID:oder klug sein objectRegisteredForID:, die keine Fehler auslösen. oder verwenden Sie eine ordnungsgemäß konfigurierte Abrufanforderung.]

rgeorge
quelle
11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDist wahrscheinlich nützlich, wenn Sie nur sehen möchten, ob ein Objekt bereits im Kontext vorhanden ist, und es nicht abrufen möchten.
Tony
Meine Situation. Auf -tableView:didSelectRowAtIndexPath: UIAlertView wird mit Ja / Nein angezeigt. Auf "Ja" - es gibt einige Arbeiten mit Objekt. Ich verwende NSFetchedResultsController+ Hintergrund-CoreData-Updates von Remote. Ich kann also kein Objekt speichern: Während die Warnung auf dem Bildschirm angezeigt wird, kann der Speicher aktualisiert und das Objekt entfernt werden. Ich speichere objectId und rufe es dann noch einmal im Alert-Delegaten ab. Weil ich benutze NSFetchedResultsController- alle notwendigen Objekte sind zu diesem Zeitpunkt bereits im Kontext. Wenn sich kein Objekt im Kontext befindet, sollte CoreData das Abrufen von Versuchen nicht unbrauchbar machen.
kpower
nette Antwort, danke! Diese Methodennamen sind wirklich schwierig. Es ist einfach, alles mit dem falschen durcheinander zu bringen
Schakal
Tolle Antwort, danke für die Klarstellung darüber objectWithId:- die Notwendigkeit, insertObjectzuerst anzurufen, um eine Ausnahmeregelung beim Versuch, einen Fehler auszulösen, zu verhindern, war für mich in der Tat nicht offensichtlich.
Stanislav Pankevich
3
objectRegisteredForID:Dies ist nützlich, wenn Sie eine Liste von Objekt-IDs aus einer Operation in einem anderen Kontext haben und nur diejenigen aktualisieren möchten, die möglicherweise veraltete Daten im lokalen Kontext enthalten. Dies hält Ihr Objektdiagramm (und damit die Speichernutzung) in Schach und es ist besser, als -registeredObjectsObjekt-IDs zu durchlaufen und zu überprüfen, um festzustellen, ob ein Objekt für Ihren Kontext fehlerhaft ist.
Sterling Archer
4

objectWithID:ist die Methode, nach der Sie suchen, und es ist die empfohlene Methode, dies zu tun. objectWithID:wird den NSManagedObjectContext effizient verwenden, um das Objekt nur so viele Ebenen wie nötig abzurufen - im Gegensatz zu einigen anderen Methoden, um dies zu tun. objectWithID:verwendet speicherinterne Informationen in übergeordneten Kontexten, dem persistenten Speicherkoordinator und dem persistenten Speicher selbst korrekt, bevor zum Sicherungsspeicher gewechselt wird.

Dies wird in der WWDC 2012- Sitzung "Core Data Best Practices" ausführlich behandelt .

quellish
quelle