objective c - Lehká migrace NSPersistentDocument

Translate

Snažím se provést odlehčenou migraci úložiště SQLite v Core Data. Práce na Lion 10.7.3 s Xcode 4.3.1.

Ve své podtřídě NSPersistentDocument (AccountDocument) jsem přepsal metodu použitou ke konfiguraci trvalého koordinátora obchodu, aby získal správné možnosti pro migraci:

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

(Díky Malcolmu Crawfordovi za tento tip:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Když spustím aplikaci, selže při implementaci 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 toho, co mohu zjistit z dokumentace, vypadá výchozí implementace asi takto:

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

Abych problém ladil trochu víc, přehodil jsem tuto metodu tímto:

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

(Díky Jeffu LaMarche za nápad:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

Balíček a adresa URL ukazují na místa, která očekávám (a já jsem se řídil radou Marcuse Zarry k vyčištění projektu, takže v balíčku aplikace nejsou žádné zbloudilé balíčky .mom nebo .momd:Používání mergedModelFromBundles: a správa verzí (CoreData)). Přesto se aplikace stále načítá při načítání modelu z adresy URL.

Zkontroloval jsem, že AccountDocument2.xcdatamodeld je balíček, který má dva modely pro správu verzí: AccountDocument 2.xcdatamodel a (původní) AccountDocument.xcdatamodel. Rozbalovací nabídka „Verze datového modelu jádra“ ve vlastnostech souboru je nastavena na „AccountDocument 2“.

Jediný rozdíl mezi těmito dvěma modely spočívá v tom, že jedna entita má další (a volitelný) atribut. Moje chápání je, že kvalifikuje model pro lehkou migraci.

Je zřejmé, že tady dělám něco špatně, ale netuším co. Jakákoli pomoc by byla nejvíce oceněna ...

Aktualizace:

Na Martinův návrh (a kontrola dokumentace NSPersistentDocument) jsem se pokusil použít tento kód pro přistupujícího uživatele:

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

Stále havaruje…

Aktualizace

Po několika návrzích na Twitteru jsem upgradoval na Xcode 4.3.2, ale problémy přetrvávají.

AKTUALIZACE RAGE

Právě jsem vytvořil balíček verzí modelu (AccountDocument2.xcdatamodeld) pomocí Xcode 4.2 na Snow Leopard. Po sestavení a spuštění aplikace vše funguje podle očekávání.

Pak jsem vzal balíček souboru AccountDocument2.xcdatamodeld zpět na Lion a Xcode 4.3.2. Když vytvořím a spustím aplikaci, dojde k chybě při načítání prostředku .momd. Ano, děti, to znamená, že za to může Xcode 4.3.x a kompilátor datových modelů (MOMC). Nevidím jiné řešení, než dělat všechny mé stavby na Snow Leopardovi.

Nejsem ten, kdo bash Xcode 4, ale když se ocitneme v situaci, kdy nástrojová řada nemůže vytvořit neprůhledný soubor (.mom a .momd) z neprůhledné specifikace (.xcdatamodel a .xcdatamodeld), je docela těžké buďte optimističtí ohledně stavu nástrojů pro Mac a iOS. Je směšné, že se základní součást těchto platforem rozpadá do té míry, že nemohu vytvořit a spustit svou aplikaci na nejnovější verzi SDK a vývojářských nástrojů.

Přijde na tuto aktualizaci

Další důkaz, že se jedná o vážnou chybu s překladačem datových modelů (MOMC) v Xcode 4.3.2: pokud zkopíruji balíček .momd ze složky Resource vytvořené Xcode 4.2 do mého projektu a přidám je do buildu jako Copy Files fáze budování, aplikace funguje dobře.

Také jsem provedl několik testů, kde jsem odstranil ověřovací pravidla a výchozí hodnoty pro atributy různých entit (na základě Marcusova níže uvedeného návrhu). Žádná změna, kompilátor stále vytváří neplatný .momd. Také jsem se pokusil vytvořit verzovaný model, kde NIC nebylo změněno: kompilovaný .momd pokračoval v havárii. Zdrojem problému je tedy vše, co máte ve svých současných modelech (a data, která představují).

Také si všimněte: tato chyba není izolována na NSPersistentDocument (jak jsem si původně myslel, když jsem zahájil tuto otázku.) Mohu způsobit selhání aplikace pouhým použitím[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

Prozatím budu upravovat / verzovat své modely pomocí Xcode 4.2 na Snow Leopard a přesouvat kompilované zdroje na Xcode 4.3.2 na Lion. Pokud jakýmkoli způsobem používáte Core Data, doporučuji vám udělat totéž, dokud nebude tato chyba vyřešena. Věřte mi, že celé dny budete zkoušet přijít na to, co se sakra děje, pokud ne.

Nyní odeslat radar ...

Aktualizace radaru

Právě jsem odeslal tento radar:

http://www.openradar.me/11184500

Aktualizace The Oh Crap It Must Be Lion

Právě jsem stáhl a nainstaloval Xcode 4.2 pro nástroje Lion zhttp://developer.apple.com/downloads. Ukázková aplikace použitá v Radaru stále havaruje.

(Poznámka: Xcode 4.2.1 nemůžete nainstalovat, protože platnost certifikátu použitého k podpisu DeveloperTools.pkg vypršela. Fungovat bude pouze Xcode 4.2.)

Pokud jste pod NDA, také zjistíte, že nástroje beta nejsou užitečné.

Doufám, že máte kolem kopii Snow Leoparda s Xcode 4.2:http://furbo.org/2012/03/28/vmware-for-developers/

Požadavky WTF Do Fetch se týkají aktualizace verzí entit a atributů

Via Evadne Wu na Twitteru:

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

A jak to udělala:

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

(Soubory .mom jsou binární seznamy.)

Kořenem problému je jeden požadavek na vyzvednutí. Jak to čísla do migrace dat z jednoho modelu do druhého je pro inženýr společnosti Apple přijít.

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

Všechny odpovědi

Translate

Zkompilované prostředky .momd lze načíst po změně požadavku na načítání "existingPartner" z:

name == $name

na:

name == $NAME

Je to neintuitivní, že část objektového modelu, která nemá vliv na perzistenci verzí datových přestávek a odlehčené migrace. Z dokumentace je zřejmé, že by tomu tak nemělo být:

Perspektiva Core Data na správu verzí spočívá v tom, že se zajímá pouze o vlastnosti modelu, které ovlivňují perzistenci.

Využijte síluCHOCKLOCKopravit vaše žádosti o načtení nebo je úplně smazat a spolehnout se na něNSPredicates vytvořené v kódu.

Zdroj
Translate

Myslím, že musíte uložit model spravovaného objektu do proměnné instance. Vracíte autorelease objekt, což pravděpodobně způsobuje špatný přístup.

Zdroj
Translate

Na základě vaší teorie, že jde o problém s MOMC, máte nějaká ověřovací pravidla v mámě?

Viděl jsem zprávy, kde ověřovací pravidla nepřežila 4.x MOMC.

Zdroj
Z S
Translate

To by mohlo trochu souviset s problémem, který jsem měl s používáním Fetch Requests, když iOS5 poprvé vyšel v beta verzi. Způsobovalo to upozornění na sestavení a při spuštění by došlo k selhání aplikace. Opravdu jsem nepoužíval požadavek na načtení, takže jsem ho odstranil a vše fungovalo dobře:Varování základních dat: „Informace o hash verze není k dispozici pro všechny modely“

Zdroj
Leave a Reply
You must be logged in to post a answer.
O autorovi