objective c - Migrazione leggera di un documento NSPersistent

Translate

Sto cercando di eseguire una migrazione leggera di un archivio SQLite in Core Data. Lavorare su Lion 10.7.3 con Xcode 4.3.1.

Nella mia sottoclasse NSPersistentDocument (AccountDocument), ho sovrascritto il metodo utilizzato per configurare il coordinatore del negozio persistente in modo che ottenga le opzioni corrette per la migrazione:

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

(Grazie a Malcolm Crawford per il suggerimento:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Quando eseguo l'app, non riesce nell'implementazione di NSPersistentDocument di-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

Da quello che posso dire dalla documentazione, l'implementazione predefinita è simile a questa:

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

Quindi, per eseguire il debug del problema un po 'di più, ho sovrascritto quel metodo con questo:

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

(Grazie a Jeff LaMarche per l'idea:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

Il bundle e l'URL puntano entrambi ai posti che mi aspetto (e ho seguito il consiglio di Marcus Zarra di pulire il progetto in modo che non ci siano bundle .mom o .momd randagi nel pacchetto dell'applicazione:Utilizzo di mergedModelFromBundles: e del controllo delle versioni (CoreData)). Tuttavia l'app continua a bloccarsi durante il caricamento del modello dall'URL.

Ho verificato che AccountDocument2.xcdatamodeld è un pacchetto che ha due modelli per il controllo delle versioni: AccountDocument 2.xcdatamodel e (l'originale) AccountDocument.xcdatamodel. Il menu a comparsa "Versioned Core Data Model" nelle proprietà del file è impostato su "AccountDocument 2".

L'unica differenza tra i due modelli è che un'entità ha un attributo aggiuntivo (e opzionale). La mia comprensione è che qualifica il modello per una migrazione leggera.

Ovviamente sto facendo qualcosa di sbagliato qui, ma non ho idea di cosa. Qualsiasi aiuto sarebbe molto apprezzato ...

Aggiornare:

Per suggerimento di Martin (e un controllo della documentazione di NSPersistentDocument) ho provato a utilizzare questo codice per l'accessor:

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

Ancora in crash ...

Aggiornare

Dopo alcuni suggerimenti su Twitter, ho aggiornato a Xcode 4.3.2, ma i problemi persistono.

RAGE UPDATE

Ho appena creato il pacchetto del modello con versione (AccountDocument2.xcdatamodeld) utilizzando Xcode 4.2 su Snow Leopard. Dopo aver creato ed eseguito l'app, tutto funziona come previsto.

Ho quindi ripreso il pacchetto di file AccountDocument2.xcdatamodeld su Lion e Xcode 4.3.2. Quando creo ed eseguo l'app, continua a bloccarsi durante il caricamento della risorsa .momd. Sì ragazzi, questo significa che la colpa è di Xcode 4.3.xe del Data Model Compiler (MOMC). Non vedo una soluzione alternativa oltre a fare tutte le mie build su Snow Leopard.

Non sono il tipo che colpisce Xcode 4, ma quando ci troviamo in una situazione in cui la toolchain non può produrre un file opaco (.mom e .momd) da una specifica opaca (.xcdatamodel e .xcdatamodeld) è piuttosto difficile essere ottimista sullo stato degli strumenti Mac e iOS. È ridicolo che un componente principale di queste piattaforme si rompa al punto in cui non riesco a creare ed eseguire la mia app sull'ultima versione dell'SDK e degli strumenti per sviluppatori.

È arrivato questo aggiornamento

Un'ulteriore prova che si tratta di un bug serio con il compilatore del modello di dati (MOMC) in Xcode 4.3.2: se copio il bundle .momd dalla cartella Resource creata da Xcode 4.2 nel mio progetto e lo aggiungo alla build come Copia file fase di compilazione, l'applicazione funziona correttamente.

Ho anche fatto alcuni test in cui ho rimosso le regole di convalida e i valori predefiniti per gli attributi delle varie entità (in base al suggerimento di Marcus di seguito). Nessuna modifica, il compilatore crea ancora un .momd non valido. Ho anche provato a creare un modello con versione in cui NULLA è stato modificato: il .momd compilato ha continuato a bloccarsi. Quindi qualunque cosa tu abbia nei tuoi modelli attuali (e dati che rappresentano) è la fonte del problema.

Inoltre da notare: questo bug non è isolato su NSPersistentDocument (come pensavo inizialmente quando ho iniziato questa domanda).[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

Per ora, modificherò / versionerò i miei modelli usando Xcode 4.2 su Snow Leopard e sposterò le risorse compilate su Xcode 4.3.2 su Lion. Se utilizzi Core Data in qualsiasi modo, ti suggerisco di fare lo stesso finché questo bug non viene risolto. Credimi, passerai giorni a cercare di capire cosa diavolo sta succedendo se non lo fai.

Ora per inviare un radar ...

Aggiornamento radar

Ho appena inviato questo Radar:

http://www.openradar.me/11184500

The Oh Crap It Must Be Lion Update

Ho appena scaricato e installato Xcode 4.2 per gli strumenti Lion dahttp://developer.apple.com/downloads. L'applicazione di esempio utilizzata nel Radar continua a bloccarsi.

(Nota: non è possibile installare Xcode 4.2.1 perché il certificato utilizzato per firmare DeveloperTools.pkg è scaduto. Solo Xcode 4.2 funzionerà.)

Se sei sotto NDA, scoprirai anche che gli strumenti beta non sono utili.

Spero che tu abbia una copia di Snow Leopard con Xcode 4.2 in giro:http://furbo.org/2012/03/28/vmware-for-developers/

Le richieste di recupero WTF hanno a che fare con le entità con versione e l'aggiornamento degli attributi

Via Evadne Wu su Twitter:

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

E come l'ha fatto:

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

(I file .mom sono plist binari.)

La radice del problema è una singola richiesta di recupero. Spetta a un ingegnere di Apple capire come questo si traduca in una migrazione di dati da un modello a un altro.

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

Tutte le risposte

Translate

Le risorse .momd compilate possono essere caricate dopo che una richiesta di recupero "existingPartner" è stata modificata da:

name == $name

per:

name == $NAME

È controintuitivo che una parte del modello a oggetti che non influisce sulla persistenza dei dati interrompa il controllo delle versioni e la migrazione leggera. È chiaro dalla documentazione che questo non dovrebbe essere il caso:

La prospettiva di Core Data sul controllo delle versioni è che interessa solo le caratteristiche del modello che influenzano la persistenza.

Usa il potere diCHOCKLOCKper correggere le tue richieste di recupero o eliminarle completamente e fare affidamento suNSPredicates creati nel codice.

fonte
Translate

Penso che sia necessario memorizzare il modello a oggetti gestito in una variabile di istanza. Stai restituendo un oggetto rilasciato automaticamente, che è probabilmente la causa dell'accesso non corretto.

fonte
Translate

Sulla base della tua teoria secondo cui si tratta di un problema con il MOMC, hai regole di convalida nella mamma?

Ho visto rapporti in cui le regole di convalida non sopravvivono al 4.x MOMC.

fonte
Z S
Translate

Questo potrebbe essere in qualche modo correlato a un problema che ho avuto con l'utilizzo delle richieste di recupero quando iOS5 è uscito per la prima volta in versione beta. Stava causando un avviso di build e avrebbe bloccato l'app all'avvio. Non stavo davvero utilizzando la richiesta di recupero, quindi l'ho rimossa e tutto ha funzionato bene:Avviso sui dati principali: "Informazioni sull'hash della versione non disponibili per tutti i modelli"

fonte
Leave a Reply
You must be logged in to post a answer.
Circa l'autore