Domanda

Nella mia app, ho un NSDictionary cui chiavi dovrebbero essere le istanze di una sottoclasse di NSManagedObject.

Il problema, tuttavia, è che NSManagedObject non implementa il protocollo NSCopying il che significa che nessun oggetto Core Data / istanze di NSManagedObject possono essere utilizzati come chiavi del dizionario, anche se il metodo -[hash] funziona bene per loro.

Was devo fare?

È stato utile?

Soluzione

Ci sono quattro opzioni:

  1. Utilizzare un oggetto diverso, come la chiave del dizionario, invece, e di ricerca da questo. [object objectID] o +[NSValue valueWithNonretainedObject:] sembrano la più ovvia
  2. Usa CFDictionaryCreateMutable() per creare un dizionario con mantenuto chiavi, piuttosto che copiato, invece, e quindi chiamare CFDictionarySetValue() per memorizzare gli oggetti
  3. Su OS X o iOS6 +, [NSMapTable mapTableWithStrongToStrongObjects] ti dà una puramente Objective-C equivalente a CFMutableDictionary
  4. Implementare NSCopying per la vostra sottoclasse oggetto gestito, in modo da tornare auto (con un conteggio di riferimento urtato se non si sta usando ARC)

Note

+valueWithNonretainedObject: è piuttosto pericoloso, dal momento che è possibile essere lasciato con un puntatore penzoloni; probabilmente meglio evitare.

Memorizzazione ID oggetto va bene, a parte il fatto che nuovo oggetti iniziano la vita con un temporaneo ID. Questo ID cambia poi a un permanente uno quando il contesto è salvato su disco (o -obtainPermanentIDsForObjects:… si chiama). Il tuo codice di mappatura deve essere abbastanza intelligente per gestire questo a meno che non può garantire che tutti gli oggetti in arrivo già hanno un ID permanente.

L'implementazione NSCopying come questo si sente un po 'icky, ma dovrebbe funzionare bene. Si dà il caso, questo è esattamente il NSURLSessionTask approccio prende, presumo per dizionario cordialità.

Prima di OS X 10.8 Mountain Lion, è usato per essere possibile creare un NSMutableDictionary regolare e quindi chiamare CFDictionarySetValue() per esso. Questo non è più il caso, però; nuovi dizionari hanno ora callback copia corretta specificati giù al livello di CF, piuttosto che puramente essere una caratteristica di NSMutableDictionary.

Altri suggerimenti

Potrebbe creare una classe wrapper, che contiene un riferimento all'istanza di NSManagedObject che si desidera utilizzare come chiave dizionario? Si potrebbe quindi rendere questa classe wrapper implementare NSCopying, insieme a un metodo di hash (forse solo chiamando il metodo hash del NSManagedObject), e utilizzare questo wrapper come chiave del dizionario.

Suggerisco di usare [[[myManagedObject objectID] URIRepresentation] absoluteString] come chiave.

Ho avuto un problema simile, in cui avevo bisogno di raggruppare più soggetti con dati aggiuntivi per ciascuno, e inizialmente provato:

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

questo non ha funzionato per la ragione di cui sopra (NSCopying), così ho fatto:

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

Ma questa soluzione ha senso solo se non è necessario accedere stile dizionario per queste entità o sei felice di iterare per trovare ciò che serve. Nel mio caso questo è stato un problema di imballaggio. Si noti che se si passa queste entità in tutto il NSManagedObjectContext deve essere lo stesso per usarli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top