objective c - Migração leve de um NSPersistentDocument

Translate

Estou tentando fazer uma migração leve de uma loja SQLite no Core Data. Trabalhando no Lion 10.7.3 com Xcode 4.3.1.

Em minha subclasse NSPersistentDocument (AccountDocument), substituí o método usado para configurar o coordenador de armazenamento persistente para que ele obtenha as opções adequadas para a migração:

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

(Obrigado a Malcolm Crawford por essa dica:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Quando eu executo o aplicativo, ele falha na implementação de NSPersistentDocument de-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

Pelo que posso dizer com a documentação, a implementação padrão se parece com isto:

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

Então, para depurar o problema um pouco mais, eu substituí esse método por este:

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

(Obrigado a Jeff LaMarche pela ideia:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

O pacote e o url apontam para os lugares que espero (e segui o conselho de Marcus Zarra para limpar o projeto para que não haja pacotes .mom ou .momd perdidos no pacote do aplicativo:Usando mergedModelFromBundles: e controle de versão (CoreData)) Mesmo assim, o aplicativo continua travando enquanto carrega o modelo do url.

Verifiquei se o AccountDocument2.xcdatamodeld é um pacote que possui dois modelos de controle de versão: AccountDocument 2.xcdatamodel e (o original) AccountDocument.xcdatamodel. O menu popup "Versioned Core Data Model" nas propriedades do arquivo é definido como "AccountDocument 2".

A única diferença entre os dois modelos é que uma Entidade possui um Atributo adicional (e opcional). Meu entendimento é que qualifica o modelo para uma migração leve.

Obviamente, estou fazendo algo errado aqui, mas não tenho ideia do quê. Qualquer ajuda seria muito apreciada…

Atualizar:

Por sugestão de Martin (e uma verificação da documentação NSPersistentDocument), tentei usar este código para o acessador:

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

Ainda travando ...

Atualizar

Após algumas sugestões no Twitter, atualizei para o Xcode 4.3.2, mas os problemas persistem.

RAGE UPDATE

Acabei de criar o pacote de modelo com versão (AccountDocument2.xcdatamodeld) usando o Xcode 4.2 no Snow Leopard. Depois de criar e executar o aplicativo, tudo funciona conforme o esperado.

Em seguida, peguei o pacote de arquivos AccountDocument2.xcdatamodeld de volta para o Lion e o Xcode 4.3.2. Quando eu construo e executo o aplicativo, ele continua travando enquanto carrego o recurso .momd. Sim, crianças, isso significa que o Xcode 4.3.x e o Data Model Compiler (MOMC) são os culpados. Não vejo uma solução alternativa além de fazer todas as minhas compilações no Snow Leopard.

Não sou de atacar o Xcode 4, mas quando nos encontramos em uma situação em que o conjunto de ferramentas não pode produzir um arquivo opaco (.mom e .momd) a partir de uma especificação opaca (.xcdatamodel e .xcdatamodeld) é muito difícil esteja otimista sobre o estado das ferramentas do Mac e iOS. É ridículo que um componente central dessas plataformas seja quebrado a ponto de não conseguir construir e executar meu aplicativo na versão mais recente do SDK e das ferramentas de desenvolvedor.

Chegou a esta atualização

Mais uma prova de que este é um bug sério com o Data Model Compiler (MOMC) no Xcode 4.3.2: se eu copiar o pacote .momd da pasta Resource criada pelo Xcode 4.2 em meu projeto e adicioná-los à compilação como um arquivo de cópia fase de construção, o aplicativo funciona bem.

Eu também fiz alguns testes em que removi regras de validação e valores padrão para os Atributos das várias Entidades (com base na sugestão de Marcus abaixo). Sem alteração, o compilador ainda cria um .momd inválido. Também tentei criar um modelo com versão em que NADA foi alterado: o .momd compilado continuou a falhar. Portanto, o que quer que você tenha em seus modelos atuais (e os dados que eles representam) é a fonte do problema.

Também digno de nota: este bug não está isolado em NSPersistentDocument (como eu pensava originalmente quando comecei esta pergunta). Posso fazer com que um aplicativo trave apenas usando[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

Por enquanto, estarei editando / criando versões de meus modelos usando o Xcode 4.2 no Snow Leopard e movendo os recursos compilados para o Xcode 4.3.2 no Lion. Se você usa Core Data de alguma forma, sugiro que faça o mesmo até que esse bug seja corrigido. Acredite em mim, você vai passar dias tentando descobrir o que diabos está acontecendo se não o fizer.

Agora, para enviar um radar ...

Atualização de radar

Acabei de enviar este Radar:

http://www.openradar.me/11184500

Atualização do Oh Crap, Deve ser Leão

Acabei de baixar e instalar as ferramentas do Xcode 4.2 for Lion dehttp://developer.apple.com/downloads. O aplicativo de amostra usado no Radar ainda trava.

(Observação: você não pode instalar o Xcode 4.2.1 porque o certificado usado para assinar o DeveloperTools.pkg expirou. Apenas o Xcode 4.2 funcionará.)

Se você estiver sob o NDA, também descobrirá que as ferramentas beta também não são úteis.

Espero que você tenha uma cópia do Snow Leopard com Xcode 4.2 disponível:http://furbo.org/2012/03/28/vmware-for-developers/

O WTF Do Fetch Requests tem a ver com a atualização de entidades e atributos com versão

Via Evadne Wu no Twitter:

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

E como ela fez isso:

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

(os arquivos .mom são plistas binários.)

A raiz do problema é um único Fetch Request. Como isso ocorre em uma migração de dados de um modelo para outro é para um engenheiro da Apple descobrir.

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

Todas as respostas

Translate

Os recursos .momd compilados podem ser carregados depois que uma solicitação de busca "existingPartner" é alterada de:

name == $name

para:

name == $NAME

É contra-intuitivo que uma parte do modelo de objeto que não afeta a persistência dos dados quebre o controle de versão e a migração leve. Está claro pela documentação que este não deveria ser o caso:

A perspectiva da Core Data sobre o controle de versão é que ela está interessada apenas nos recursos do modelo que afetam a persistência.

Use o poder doCHOCKLOCKpara corrigir seus Fetch Requests ou excluí-los completamente e confiar emNSPredicates criados em código.

Fonte
Translate

Acho que você precisa armazenar o modelo de objeto gerenciado em uma variável de instância. Você está retornando um objeto liberado automaticamente, o que provavelmente está causando o mau acesso.

Fonte
Translate

Com base na sua teoria de que é um problema com o MOMC, você tem alguma regra de validação na mãe?

Tenho visto relatórios em que as regras de validação não sobrevivem ao MOMC 4.x.

Fonte
Z S
Translate

Isso pode estar relacionado a um problema que tive com o uso de Fetch Requests quando o iOS5 foi lançado em beta. Estava causando um aviso de build e travava o aplicativo na inicialização. Eu não estava realmente usando a solicitação de busca, então a removi e tudo funcionou bem:Aviso de dados principais: "Informações de hash de versão não disponíveis para todos os modelos"

Fonte
Leave a Reply
You must be logged in to post a answer.
Sobre o autor