Out-of-Memory während der Core-Datenmigration

8

Ich migriere ein CoreData-Modell zwischen zwei Versionen einer Anwendung. Ich habe binäre Daten als Blobs in der vorherigen Version gespeichert, und ich möchte sie aus den Blobs für die Leistung entfernen. Mein Problem ist, dass es während der Migration so aussieht, als ob Core Data alles in den Speicher lädt, was zu Low Memory Warnings führt und dann dazu führt, dass meine App getötet wird.

Die Apple-Dokumentation schlägt Folgendes vor: Ссылка

Es scheint sich jedoch auf die Tatsache zu verlassen, dass die großen Objekte unterschiedlich kartiert werden. In meinem Fall sind alle Objekte im Grunde gleich und auf jedes von ihnen muss das gleiche Mapping angewendet werden. Ich sehe in diesem Fall nicht, wie ich ihre Technik anwenden könnte.

Wie sollte ich eine Migration mit sehr großen Objekten handhaben?

    
Kamchatka 18.12.2010, 17:40
quelle

1 Antwort

2

Ich vermute, dass Sie eine Reihe von Änderungen vornehmen müssen, die Sie zusätzlich zu den Daten aus den Blobs machen möchten. Mein Vorschlag ist, die Migration in ein paar Stufen durchzuführen. Ich denke hier irgendwie laut nach, also könnte es möglich sein, das zu verbessern. Dazu müssen Sie SQLite verwenden.

Damit das funktioniert, haben Sie drei Versionen Ihres Modells:

  1. Das ursprüngliche Modell
  2. Das Modell mit dem Attribut entfernt (und möglicherweise mit einer speziellen eindeutigen ID hinzugefügt - siehe unten)
  3. Das Modell mit allen von Ihnen vorgenommenen Änderungen, einschließlich des Hinzufügens der neuen Entität und der Beziehungen, die das Attribut
  4. ersetzen

Der Grund dafür ist, dass der Übergang von Version 1 zu 2 mit einer automatischen Lightweight-Migration möglich sein sollte. In diesem Fall muss Core Data nichts in den Speicher laden - es werden nur SQL-Anweisungen ausgegeben, um die Änderungen direkt in der Datenbank vorzunehmen.

Sie beginnen damit, Ihren persistenten Store-Koordinator mit der alten Modellversion einzurichten. Nachdem Sie die Daten geladen haben, durchlaufen Sie alle Objekte, die Sie migrieren, extrahieren Sie das Binärattribut und schreiben Sie es irgendwie auf den Datenträger. Sie können eine Abrufanforderung mit Batch-Entleerung und regelmäßigem Autorelease-Pool-Entleeren verwenden, um sicherzustellen, dass nicht zu viel Speicher für temporäre Objekte belegt wird. Speichern Sie die Daten in dem Verzeichnis, das Sie mit NSCachesDirectory erhalten. Sie möchten die Daten natürlich so speichern, dass Sie sie wieder mit der verwalteteObjektID des Objekts verknüpfen können.

Dann schließen Sie alles und bitten Core Data, den Speicher von Version 1 auf Version 2 zu migrieren. Weitere Informationen finden Sie unter diesen Link für Details. Öffnen Sie den Laden mit Version 2.

Sie müssen möglicherweise einen Schritt hinzufügen, bei dem Sie jedem Objekt eine eindeutige ID zuweisen, da ich nicht sicher bin, ob Core Data Objekt-IDs bei einer nicht leichten Migration verwaltet. Wenn Sie dies tun müssen, würde Ihr Modell der Version 2 dem Objekt, dem Sie die Binärdaten entnehmen, ein neues Attribut hinzufügen, das entweder optional ist oder einen Standardwert hat. Da die einfache Migration die managedObjectIDs nicht ändern sollte, können Sie die Zuordnung Ihrer neuen eindeutigen ID zu den managedObjectIDs speichern, die Sie zusammen mit den binären Daten vor zwei Absätzen gespeichert haben.

Speichern Sie die Daten und schließen Sie das Geschäft.

Öffnen Sie den Store und führen Sie eine Migration von Version 2 zu Version 3 durch. Dies sollte im Grunde der Code sein, den Sie bereits geschrieben haben, bevor Sie die Frage gepostet haben. Sobald der Store geöffnet ist, fügen Sie alle Objekte hinzu, die Sie im Store der Version 1 gespeichert haben, und richten Sie die Beziehungen mit den Daten ein, die Sie auf dem Weg gespeichert haben.

Einfach, oder?

    
Jacques 09.01.2011, 02:50
quelle