Pergunta

No meu aplicativo, eu tenho um NSDictionary cujas chaves devem ser instâncias de uma subclasse de NSManagedObject.

O problema, no entanto, é que NSManagedObject não implementa o NSCopying protocolo, o que significa que nenhum dados principal de dados / instâncias de NSManagedObject pode ser usado como teclas de dicionário, embora o -[hash] O método funciona bem para eles.

Devo fazer?

Foi útil?

Solução

Existem quatro opções:

  1. Use um objeto diferente como a chave do dicionário e a pesquisa disso. [object objectID] ou +[NSValue valueWithNonretainedObject:] parece o mais óbvio
  2. Usar CFDictionaryCreateMutable() para criar um dicionário com retido chaves, em vez de copiar, em vez disso, e depois ligue CFDictionarySetValue() Para armazenar os objetos
  3. No OS X ou iOS6+, [NSMapTable mapTableWithStrongToStrongObjects] dá a você um equivalente puramente objetivo-C a CFMutableDictionary
  4. Implemento NSCopying Para a sua subclasse de objeto gerenciado, de modo que ele retorne a si (com uma contagem de referência esbarrada se você não estiver usando o ARC)

Notas

+valueWithNonretainedObject: é bastante perigoso, já que é possível ficar com um ponteiro pendurado; Provavelmente melhor evitar.

Armazenar IDs de objeto é bom, além do fato de que novo objetos começam a vida com um temporário EU IRIA. Esse ID muda para um permanente quando o contexto é salvo para disco (ou -obtainPermanentIDsForObjects:… é chamado). Seu código de mapeamento precisa ser inteligente o suficiente para lidar com isso, a menos que possa garantir que todos os objetos recebidos já tenham um ID permanente.

Implementação NSCopying Como se isso pareça um pouco nojento, mas deve funcionar muito bem. Por acaso, essa é exatamente a abordagem NSURLSessionTask toma, presumo que a amizade do dicionário.

Antes do OS X 10.8 Mountain Lion, costumava ser possível criar um regular NSMutableDictionary e então ligue CFDictionarySetValue() para isso. Esse não é mais o caso; Novos dicionários agora têm retornos de chamada de cópia adequados especificados no nível da CF, em vez de ser puramente um recurso de NSMutableDictionary.

Outras dicas

Você poderia criar uma classe de wrapper, que contém uma referência à instância do NSmanAgedObject que deseja usar como chave de dicionário? Você pode fazer essa classe de wrapper implementar o NScopying, juntamente com um método de hash (talvez apenas chamando o método de hash do NmanAgedObject) e usar esse invólucro como chave do dicionário.

Eu sugiro usar [[[myManagedObject ObjectId] URirepresentation] absolvestring] como sua chave.

Eu tive um problema semelhante, no qual precisava agrupar várias entidades com dados adicionais para cada um, e inicialmente tentou:

@{entity1:data1, @entity2:data2, @entity3:data3}

Isso não funcionou pelo motivo acima (NScopying), então eu fiz:

@[
   @{@"entity":entity1, @"data":data1},
   @{@"entity":entity2, @"data":data2},
   @{@"entity":entity3, @"data":data3}
]

Mas essa solução faz sentido apenas se você não precisar de acesso ao estilo de dicionário a essas entidades ou ficar feliz em iterar para encontrar o que você precisa. No meu caso, este foi um problema de embalagem. Observe que, se você passar por essas entidades em torno do NSmanAgedObjectContext, precisará ser o mesmo para usá -las.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top