Wie kann ich kopieren oder verschieben Sie ein NSManagedObject von einem Kontext in einen anderen?
Habe ich, was ich davon ausgehen ist ein ziemlich standard-setup, mit einem Notizblock MOC, die wird nie gespeichert (enthält eine Reihe von Objekten aus dem Internet heruntergeladen) und einem anderen dauerhaften MOC, die weiterhin Objekte. Wenn der Benutzer wählt ein Objekt aus scratchMOC hinzufügen, um Ihre Bibliothek, ich möchte entweder 1) entfernen Sie das Objekt aus scratchMOC und einfügen in permanentMOC, oder 2) kopieren Sie das Objekt in permanentMOC. Die Core Data FAQ sagt, ich kann kopieren Sie ein Objekt wie dieses:
NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *copy = [context2 objectWithID:objectID];
(In diesem Fall, context2 wäre permanentMOC.) Jedoch, wenn ich dies tun, wird das kopierte Objekt ist fehlgeschlagen; die Daten zunächst ungelöst. Wenn es nicht behoben wird, später, alle Werte sind null; keine der Daten (Attribute oder Beziehungen) aus dem original-managedObject sind tatsächlich kopiert oder referenziert werden. Also ich sehe keinen Unterschied zwischen der Verwendung dieser objectWithID: Methode und das einlegen eines völlig neuen Objektes in permanentMOC mit insertNewObjectForEntityForName:.
Ich weiß, ich kann ein neues Objekt erstellen in permanentMOC und manuell kopieren Sie die einzelnen Schlüssel-Wert-paar aus dem alten Objekt, aber ich bin nicht sehr glücklich mit dieser Lösung. (Ich habe eine Reihe von verschiedenen verwalteten Objekten, für die habe ich dieses problem, so dass ich nicht wollen, zu schreiben und zu aktualisieren, kopieren: Methoden für alle von Ihnen, wie ich weiter zu entwickeln.) Gibt es einen besseren Weg?
InformationsquelleAutor Aeonaut | 2010-06-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste, die mehr als eine
NSManagedObjectContext
auf einem einzigen thread ist nicht eine standard-Konfiguration. 99% der Zeit brauchen Sie nur ein Rahmen und löst diese situation für Sie.Warum brauchst du mehr als eine
NSManagedObjectContext
?Update
Dass ist tatsächlich einer der wenigen Anwendungsfälle, die ich gesehen haben, wo das Sinn macht. Um dies zu tun, müssen Sie eine rekursive Kopie des Objekts von einem Kontext in den anderen. Der workflow wäre wie folgt:
-dictionaryWithValuesForKeys
und-[NSEntityDescription attributesByName]
um dies zu tun.-setValuesForKeysWithDictionary
)-[NSEntityDescription relationshipsByName]
Wie erwähnt von anderen, Sie können downloaden Sie den Beispielcode aus meinem Buch aus Der Pragmatische Programmierer Von Core Data Book und finden eine Lösung für dieses problem. Natürlich in dem Buch, das ich besprechen es mehr in die Tiefe 🙂
Aus irgendeinem Grund hatte ich Schwierigkeiten, den richtigen code zum ausführen von Schritt 2, also hier ist es:
NSDictionary *newValues = [oldObject dictionaryWithValuesForKeys:[[objectEntity attributesByName] allKeys]]
Könntest du bitte erläutern warum sollte nicht auch einer lieber mit mehr als einem NSManagedObjectContext in einem einzigen thread? Gibt es irgendwelche Auswirkungen, wenn wir das so machen? Danke!
ist diese Meinung immer noch gültig, mit CoreData Verbesserungen wie Eltern-Kind-MOCs jetzt? Denn es scheint mir nun, dass mehrere MOCs ist nicht nur okay, sondern empfohlen, auch bei einfachen Fällen wie erstellen Sie ein neues Objekt wählen Sie dann Abbrechen/speichern. Das Apple-Beispiel CoreDataBooks jetzt tut dies mit mehreren MOCs.
"NSManagedObjectContext in einem einzigen thread ist nicht ein standard" -- absolut nicht wahr
InformationsquelleAutor Marcus S. Zarra
In der Dokumentation ist irreführend und unvollständig. Die objectID-Methoden nicht selbst Objekte kopieren Sie einfach garantieren, dass Sie bekommen haben, das spezifische Objekt, das Sie wollte.
Den
context2
im Beispiel ist in der Tat die Quelle Kontext, und nicht das Ziel. Sie bekommen eine null, weil die Ziel-Rahmen hat kein Objekt mit dieser ID.Kopieren verwalteten Objekte ist relativ beteiligten aufgrund der Komplexität der Objekt-graph und die Art und Weise, dass der Kontext, Verwaltung der Graphen. Sie haben zu reproduzieren, ist das kopierte Objekt im detail in einen neuen Kontext.
Hier finden Sie einige Beispiel-code , dass ich geschnippelt aus der Beispiel-code für Der Pragmatische Programmierer Core Data: Apple ' s API zum speichern von Daten auf dem Mac OS X. (Vielleicht sind Sie in der Lage, zum download der gesamten Projekt-code, ohne den Kauf des Buches auf die Pragmatische Seite.) Es soll Ihnen eine grobe Vorstellung, wie gehen Sie zum kopieren eines Objekts zwischen Kontext.
Können Sie einige Basis-code, der kopiert Objekte, aber die Angaben zu jedem Objekt-Diagramm Beziehungen bedeuten in der Regel, dass Sie haben, passen Sie für jedes Daten-Modell.
copyObject
ist-Objekts kopiert werden.toContext
Ziel-Kontext.parentEntity
Superklasse. Aber was ist[self lookup]
was Klasse ist selbst? Wo kommt dieser code Leben?Ok, ich glaube ich habe es. Die
lookup
ist nur ein Wörterbuch zu vermeiden, duplizieren der gleiche Gegenstand zweimal bei der Traversierung des Objekt-Graphen.Hai, erstmal danke für das snippet, es ist genial! Wenn ich diesen code auf ein Beispiel (Event-und Geräte-Modelle, Ereignis creatingDevice, Gerät hat Veranstaltungen) Hole ich meine alle die Ereignisse, dann die Funktion aufrufen, dann rufen Sie save() auf den neuen Kontext und eine Ausnahme wirft, sagen creatingDevice ist null... Was mache ich falsch? Danke!
InformationsquelleAutor TechZen
Hatte das gleiche problem selber und fand diesen Artikel erstellt getrennte Entitäten, die später Hinzugefügt werden, um die Kontext: http://locassa.com/temporary-storage-in-apples-coredata/
Die Idee ist, dass Sie ein NSManagedObject, weil Sie gehen, um das speichern von Objekten in der Datenbank. Meine Hürde war, dass viele dieser Objekte heruntergeladen werden-via HTTP-API und ich werfen wollen sich die meisten von Ihnen am Ende der Sitzung. Denken Sie an einen stream der user Beiträge, und ich möchte nur das speichern der Favoriten-oder als Entwurf gespeichert.
Erstelle ich alle meine Beiträge mit
und dann die Beiträge eingefügt werden, um die lokalen managed-object-context-wenn Sie Favoriten
Hoffe, das hilft.
InformationsquelleAutor Anthony
Müssen Sie sicherstellen, dass Sie sparen Rahmen, dass
managedObject
lebt. Damit Holen Sie sich das gleiche Objekt in einem anderen Kontext, es muss vorhanden sein, in die persistente Speicherung.Laut die Dokumentation,
objectWithID:
immer ein Objekt zurück. Also die Tatsache, dass der Fehler behebt, die auf ein Objekt werden allenil
Werte impliziert, dass es nicht der Suche nach Ihrem Objekt in den persistenten Speicher.Werfen Sie einen Blick auf die in-memory-store geben. Es ist ein Geschäft, das lebt nur dann in den Speicher und geht Weg, wenn das Programm beendet wird. Nur vorsichtig sein, dass Sie nicht haben Beziehungen in den Filialen.
Alex, das sieht sehr verlockend, aber ich bin mit ein wenig Mühe, herauszufinden, wie es funktioniert. Sind die beiden Läden (persistente und in-memory) in zwei separaten Kontexten oder in der gleichen?
InformationsquelleAutor Alex