objective c - Leichte Migration eines NSPersistentDocument

Translate

Ich versuche, eine einfache Migration eines SQLite-Speichers in Core Data durchzuführen. Arbeiten an Lion 10.7.3 mit Xcode 4.3.1.

In meiner NSPersistentDocument-Unterklasse (AccountDocument) habe ich die Methode überschrieben, mit der der persistente Speicherkoordinator so konfiguriert wurde, dass er die richtigen Optionen für die Migration erhält:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
    NSMutableDictionary *newStoreOptions;
    if (storeOptions == nil) {
        newStoreOptions = [NSMutableDictionary dictionary];
    }
    else {
        newStoreOptions = [storeOptions mutableCopy];
    }
    [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

    BOOL result = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newStoreOptions error:error];
    return result;
}

(Danke an Malcolm Crawford für diesen Tipp:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Wenn ich die App ausführe, schlägt dies bei der Implementierung von NSPersistentDocument fehl-managedObjectModel:

* thread #1: tid = 0x2703, 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16, stop reason = EXC_BAD_ACCESS (code=13, address=0x0)
    frame #0: 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16
    frame #1: 0x00007fff8935e975 CoreData`-[NSKnownKeysDictionary1 _setValues:retain:] + 197
    frame #2: 0x00007fff8935f288 CoreData`_newReadModelFromBytes + 648
    frame #3: 0x00007fff8935b93e CoreData`+[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) _newModelFromOptimizedEncoding:error:] + 9310
    frame #4: 0x00007fff89359451 CoreData`-[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) initWithContentsOfOptimizedURL:] + 305
    frame #5: 0x00007fff89358d7b CoreData`-[NSManagedObjectModel initWithContentsOfURL:] + 443
    frame #6: 0x00007fff893e9519 CoreData`+[NSManagedObjectModel mergedModelFromBundles:] + 377
    frame #7: 0x00007fff8ded7037 AppKit`-[NSPersistentDocument managedObjectModel] + 301
    frame #8: 0x00007fff8ded70b3 AppKit`-[NSPersistentDocument managedObjectContext] + 75
    frame #9: 0x00007fff8ded6e3f AppKit`-[NSPersistentDocument _persistentStoreCoordinator] + 18
    frame #10: 0x00007fff8ded6b5d AppKit`-[NSPersistentDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 51
    frame #11: 0x0000000100003193 BeanCounter`-[AccountDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 419 at AccountDocument.m:298

Nach dem, was ich aus der Dokumentation ersehen kann, sieht die Standardimplementierung ungefähr so aus:

- (id)managedObjectModel
{
    NSManagedObjectModel *result = [NSManagedObjectModel mergedModelFromBundles:nil];
    return result;
}

Um das Problem ein wenig weiter zu debuggen, habe ich diese Methode folgendermaßen überschrieben:

- (id)managedObjectModel
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
    NSManagedObjectModel *result = [[[NSManagedObjectModel alloc] initWithContentsOfURL:url] autorelease];  
    return result;
}

(Danke an Jeff LaMarche für die Idee:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

Das Bundle und die URL zeigen beide auf die Stellen, die ich erwarte (und ich habe Marcus Zarras Rat befolgt, das Projekt zu bereinigen, damit das Anwendungspaket keine streunenden .mom- oder .momd-Bundles enthält:MergedModelFromBundles verwenden: und Versionierung (CoreData)). Die App stürzt jedoch weiterhin ab, während das Modell von der URL geladen wird.

Ich habe überprüft, ob AccountDocument2.xcdatamodeld ein Paket ist, das zwei Versionsmodelle enthält: AccountDocument 2.xcdatamodel und (das Original) AccountDocument.xcdatamodel. Das Popup-Menü "Versioniertes Kerndatenmodell" in den Dateieigenschaften ist auf "AccountDocument 2" eingestellt.

Der einzige Unterschied zwischen den beiden Modellen besteht darin, dass eine Entität ein zusätzliches (und optionales) Attribut hat. Mein Verständnis ist, dass das Modell für eine einfache Migration qualifiziert ist.

Natürlich mache ich hier etwas falsch, aber ich habe keine Ahnung was. Jede Hilfe wäre sehr dankbar ...

Aktualisieren:

Gemäß Martins Vorschlag (und einer Überprüfung der NSPersistentDocument-Dokumentation) habe ich versucht, diesen Code für den Accessor zu verwenden:

- (id)managedObjectModel
{
    static id sharedManagedObjectModel = nil;

    if (sharedManagedObjectModel == nil) {
        NSBundle *bundle = [NSBundle mainBundle];
        NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
        sharedManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
    }

    return sharedManagedObjectModel;
}

Immer noch abstürzen ...

Aktualisieren

Nach einigen Vorschlägen auf Twitter habe ich ein Upgrade auf Xcode 4.3.2 durchgeführt, aber die Probleme bestehen weiterhin.

RAGE UPDATE

Ich habe gerade das versionierte Modellpaket (AccountDocument2.xcdatamodeld) mit Xcode 4.2 auf Snow Leopard erstellt. Nach dem Erstellen und Ausführen der App funktioniert alles wie erwartet.

Ich habe dann das Dateipaket AccountDocument2.xcdatamodeld wieder auf Lion und Xcode 4.3.2 übertragen. Wenn ich die App erstelle und ausführe, stürzt sie beim Laden der .momd-Ressource weiterhin ab. Ja, Kinder, das heißt, Xcode 4.3.x und der Data Model Compiler (MOMC) sind schuld. Ich sehe keine andere Problemumgehung als alle meine Builds auf Snow Leopard.

Ich bin nicht derjenige, der Xcode 4 verprügelt, aber wenn wir uns in einer Situation befinden, in der die Toolchain keine undurchsichtige Datei (.mom und .momd) aus einer undurchsichtigen Spezifikation (.xcdatamodel und .xcdatamodeld) erstellen kann, ist dies ziemlich schwierig Seien Sie optimistisch über den Status der Mac- und iOS-Tools. Es ist lächerlich, dass eine Kernkomponente dieser Plattformen so stark kaputt geht, dass ich meine App nicht mit der neuesten Version des SDK und den Entwicklertools erstellen und ausführen kann.

Es ist zu diesem Update gekommen

Ein weiterer Beweis dafür, dass dies ein schwerwiegender Fehler mit dem Data Model Compiler (MOMC) in Xcode 4.3.2 ist: Wenn ich das .momd-Bundle aus dem von Xcode 4.2 erstellten Ressourcenordner in mein Projekt kopiere und als Build-Dateien zum Build hinzufüge Build-Phase, die Anwendung funktioniert gut.

Ich habe auch einige Tests durchgeführt, bei denen ich Validierungsregeln und Standardwerte für die Attribute der verschiedenen Entitäten entfernt habe (basierend auf Marcus 'Vorschlag unten). Keine Änderung, der Compiler erstellt immer noch eine ungültige .momd. Ich habe auch versucht, ein versioniertes Modell zu erstellen, bei dem NICHTS geändert wurde: Die kompilierte .momd stürzte weiterhin ab. Was auch immer Sie in Ihren aktuellen Modellen haben (und die Daten, die sie darstellen), ist die Ursache des Problems.

Ebenfalls zu beachten: Dieser Fehler ist nicht auf NSPersistentDocument beschränkt (wie ich ursprünglich dachte, als ich diese Frage gestartet habe). Ich kann eine App zum Absturz bringen, indem ich sie nur benutze[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

Im Moment werde ich meine Modelle mit Xcode 4.2 auf Snow Leopard bearbeiten / versionieren und die kompilierten Ressourcen auf Xcode 4.3.2 auf Lion übertragen. Wenn Sie Core Data in irgendeiner Weise verwenden, empfehlen wir Ihnen, dasselbe zu tun, bis dieser Fehler behoben ist. Vertrauen Sie mir, Sie werden Tage damit verbringen, herauszufinden, was zum Teufel los ist, wenn Sie es nicht tun.

Jetzt ein Radar einreichen ...

Radar Update

Ich habe gerade dieses Radar eingereicht:

http://www.openradar.me/11184500

Das Oh Mist, es muss ein Löwen-Update sein

Ich habe gerade den Xcode 4.2 für Lion-Tools von heruntergeladen und installierthttp://developer.apple.com/downloads. Die im Radar verwendete Beispielanwendung stürzt immer noch ab.

(Hinweis: Sie können Xcode 4.2.1 nicht installieren, da das zum Signieren von DeveloperTools.pkg verwendete Zertifikat abgelaufen ist. Nur Xcode 4.2 funktioniert.)

Wenn Sie unter NDA stehen, werden Sie auch feststellen, dass die Beta-Tools ebenfalls nicht hilfreich sind.

Ich hoffe, Sie haben eine Kopie von Snow Leopard mit Xcode 4.2:http://furbo.org/2012/03/28/vmware-for-developers/

Die WTF-Abrufanforderungen haben mit der Aktualisierung versionierter Entitäten und Attribute zu tun

Über Evadne Wu auf Twitter:

https://twitter.com/#!/evadne/status/187625192342818818

Und wie sie es gemacht hat:

https://twitter.com/#!/evadne/status/187629091518816258

(.mom-Dateien sind Binärlisten.)

Die Wurzel des Problems ist eine einzelne Abrufanforderung. Wie sich dies auf die Migration von Daten von einem Modell zu einem anderen auswirkt, muss ein Ingenieur bei Apple herausfinden.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Die kompilierten .momd-Ressourcen können geladen werden, nachdem eine "bestehendePartner" -Abrufanforderung geändert wurde von:

name == $name

zu:

name == $NAME

Es ist nicht intuitiv, dass ein Teil des Objektmodells, der die Persistenz von Daten nicht beeinflusst, die Versionierung und die einfache Migration unterbricht. Aus der Dokumentation geht hervor, dass dies nicht der Fall sein sollte:

Die Version von Core Data zur Versionierung besteht darin, dass nur Funktionen des Modells interessiert sind, die sich auf die Persistenz auswirken.

Nutzen Sie die Kraft derCHOCKLOCKum Ihre Abrufanforderungen zu korrigieren oder sie vollständig zu löschen und sich darauf zu verlassenIm Code erstellte NSPredicates.

Quelle
Translate

Ich denke, Sie müssen das verwaltete Objektmodell in einer Instanzvariablen speichern. Sie geben ein automatisch freigegebenes Objekt zurück, was wahrscheinlich den schlechten Zugriff verursacht.

Quelle
Translate

Basierend auf Ihrer Theorie, dass es sich um ein Problem mit dem MOMC handelt, haben Sie Validierungsregeln bei der Mutter?

Ich habe Berichte gesehen, in denen Validierungsregeln den 4.x MOMC nicht überleben.

Quelle
Z S
Translate

Dies könnte etwas mit einem Problem zu tun haben, das ich bei der Verwendung von Abrufanforderungen hatte, als iOS5 zum ersten Mal in der Beta herauskam. Es verursachte eine Build-Warnung und stürzte die App beim Start ab. Ich habe die Abrufanforderung nicht wirklich verwendet, also habe ich sie entfernt und alles hat gut funktioniert:Warnung zu Kerndaten: "Versions-Hash-Informationen sind nicht für alle Modelle verfügbar"

Quelle
Leave a Reply
You must be logged in to post a answer.
Über den Autor