objective c - Lekka migracja NSPersistentDocument

Translate

Próbuję wykonać lekką migrację sklepu SQLite w Core Data. Praca nad Lion 10.7.3 z Xcode 4.3.1.

W mojej podklasie NSPersistentDocument (AccountDocument) nadpisałem metodę używaną do skonfigurowania trwałego koordynatora magazynu, aby uzyskać odpowiednie opcje migracji:

- (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;
}

(Podziękowania dla Malcolma Crawforda za tę wskazówkę:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Kiedy uruchamiam aplikację, kończy się niepowodzeniem w implementacji NSPersistentDocument-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

Z tego, co mogę powiedzieć z dokumentacji, domyślna implementacja wygląda mniej więcej tak:

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

Aby nieco bardziej zdebugować problem, zastąpiłem tę metodę następującą:

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

(Podziękowania dla Jeffa LaMarche za pomysł:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

Pakiet i adres URL wskazują miejsca, których się spodziewam (i postępowałem zgodnie z radą Marcusa Zarry, aby wyczyścić projekt, aby w pakiecie aplikacji nie było żadnych zbłąkanych pakietów .mom ani .momd:Korzystanie z scaledModelFromBundles: i wersjonowania (CoreData)). Jednak aplikacja nadal ulega awarii podczas ładowania modelu z adresu URL.

Sprawdziłem, czy AccountDocument2.xcdatamodeld to pakiet, który ma dwa modele do wersjonowania: AccountDocument 2.xcdatamodel i (oryginalny) AccountDocument.xcdatamodel. Menu podręczne „Wersjonowany podstawowy model danych” we właściwościach pliku jest ustawione na „Dokument konta 2”.

Jedyną różnicą między tymi dwoma modelami jest to, że jedna jednostka ma dodatkowy (i opcjonalny) atrybut. Rozumiem, że model kwalifikuje się do lekkiej migracji.

Oczywiście robię tu coś nie tak, ale nie mam pojęcia, co. Każda pomoc będzie mile widziana…

Aktualizacja:

Zgodnie z sugestią Martina (i sprawdzeniem dokumentacji NSPersistentDocument) próbowałem użyć tego kodu dla akcesora:

- (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;
}

Nadal się zawiesza…

Aktualizacja

Po kilku sugestiach na Twitterze dokonałem aktualizacji do Xcode 4.3.2, ale problemy nadal występują.

RAGE UPDATE

Właśnie utworzyłem wersjonowany pakiet modelu (AccountDocument2.xcdatamodeld) przy użyciu Xcode 4.2 w systemie Snow Leopard. Po zbudowaniu i uruchomieniu aplikacji wszystko działa zgodnie z oczekiwaniami.

Następnie wziąłem pakiet plików AccountDocument2.xcdatamodeld z powrotem do Lion i Xcode 4.3.2. Kiedy tworzę i uruchamiam aplikację, nadal ulega awarii podczas ładowania zasobu .momd. Tak, dzieciaki, oznacza to, że Xcode 4.3.x i Data Model Compiler (MOMC) są winne. Nie widzę innego rozwiązania niż wykonanie wszystkich moich kompilacji w systemie Snow Leopard.

Nie jestem osobą, która atakuje Xcode 4, ale kiedy znajdujemy się w sytuacji, w której łańcuch narzędzi nie może utworzyć nieprzezroczystego pliku (.mom i .momd) z nieprzezroczystej specyfikacji (.xcdatamodel i .xcdatamodeld), jest to dość trudne bądź optymistyczny, jeśli chodzi o stan narzędzi dla komputerów Mac i iOS. To śmieszne, że podstawowy komponent tych platform psuje się do tego stopnia, że nie mogę zbudować i uruchomić mojej aplikacji na najnowszej wersji zestawu SDK i narzędzi programistycznych.

Nadchodzi ta aktualizacja

Więcej dowodu na to, że jest to poważny błąd w kompilatorze modelu danych (MOMC) w Xcode 4.3.2: jeśli skopiuję pakiet .momd z folderu zasobów utworzonego przez Xcode 4.2 do mojego projektu i dodam je do kompilacji jako plik Copy Files w fazie budowania, aplikacja działa dobrze.

Zrobiłem również kilka testów, w których usunąłem reguły walidacji i domyślne wartości dla atrybutów różnych jednostek (na podstawie sugestii Marcusa poniżej). Bez zmian, kompilator nadal tworzy nieprawidłowy plik .momd. Próbowałem również stworzyć wersjonowany model, w którym NIC nie zostało zmienione: skompilowany plik .momd nadal się zawieszał. Więc to, co masz w swoich aktualnych modelach (i danych, które reprezentują) jest źródłem problemu.

Uwaga: ten błąd nie jest izolowany do NSPersistentDocument (tak jak pierwotnie myślałem, kiedy zacząłem to pytanie). Mogę spowodować awarię aplikacji, używając po prostu[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

Na razie będę edytować / wersjonować moje modele przy użyciu Xcode 4.2 w systemie Snow Leopard i przenosić skompilowane zasoby do Xcode 4.3.2 na Lion. Jeśli używasz danych podstawowych w jakikolwiek sposób, sugeruję, abyś robił to samo, dopóki ten błąd nie zostanie naprawiony. Zaufaj mi, spędzisz dni próbując dowiedzieć się, co się dzieje, jeśli tego nie zrobisz.

Teraz przesyłam radar…

Aktualizacja radaru

Właśnie przesłałem ten radar:

http://www.openradar.me/11184500

Aktualizacja o cholera, to musi być lew

Właśnie pobrałem i zainstalowałem Xcode 4.2 dla narzędzi Lion z witrynyhttp://developer.apple.com/downloads. Przykładowa aplikacja używana w Radar nadal ulega awarii.

(Uwaga: nie można zainstalować Xcode 4.2.1, ponieważ certyfikat użyty do podpisania DeveloperTools.pkg wygasł. Tylko Xcode 4.2 będzie działać).

Jeśli jesteś objęty umową o zachowaniu poufności, przekonasz się również, że narzędzia beta również nie są pomocne.

Mam nadzieję, że masz kopię Snow Leopard z Xcode 4.2 w pobliżu:http://furbo.org/2012/03/28/vmware-for-developers/

Żądania pobrania WTF muszą zrobić z wersjonowanymi jednostkami i aktualizacją atrybutów

Via Evadne Wu na Twitterze:

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

I jak to zrobiła:

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

(pliki .mom to binarne pliki plists.)

Źródłem problemu jest pojedyncze żądanie pobrania. Inżynier z Apple powinien dowiedzieć się, w jaki sposób wpływa to na migrację danych z jednego modelu do drugiego.

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

Wszystkie odpowiedzi

Translate

Skompilowane zasoby .momd można załadować po zmianie żądania pobierania „existingPartner” z:

name == $name

do:

name == $NAME

Jest sprzeczne z intuicją, że część modelu obiektowego, która nie wpływa na trwałość danych, przerywa wersjonowanie i uproszczoną migrację. Z dokumentacji jasno wynika, że tak nie powinno być:

Punkt widzenia Core Data na wersjonowanie jest taki, że interesują go tylko te cechy modelu, które wpływają na trwałość.

Wykorzystaj mocBLOKADAaby naprawić Żądania pobierania lub całkowicie je usunąć i polegać na nichNSPredicates utworzone w kodzie.

Źródło
Translate

Myślę, że musisz przechowywać zarządzany model obiektów w zmiennej instancji. Zwracasz obiekt z autouzyskiwania, co prawdopodobnie powoduje zły dostęp.

Źródło
Translate

Opierając się na twojej teorii, że jest to problem z MOMC, czy masz jakieś zasady walidacji u mamy?

Widziałem raporty, w których reguły walidacji nie przetrwały MOMC 4.x.

Źródło
Z S
Translate

Może to być nieco związane z problemem, który miałem z korzystaniem z żądań pobierania, gdy iOS5 po raz pierwszy pojawił się w wersji beta. Powoduje to ostrzeżenie o kompilacji i powoduje awarię aplikacji podczas uruchamiania. Tak naprawdę nie korzystałem z żądania pobierania, więc je usunąłem i wszystko działało dobrze:Ostrzeżenie dotyczące podstawowych danych: „Informacje o skrótach wersji nie są dostępne dla wszystkich modeli”

Źródło
Leave a Reply
You must be logged in to post a answer.
O autorze