2011-12-29 19 views
20

Sto provando a convertire un pezzo di codice Java che utilizza una HashMap che contiene come chiave un oggetto e un valore come oggetto.Objective-C HashMap equivalente

private static HashMap<Class<? extends Component>, ComponentType> componentTypes = new HashMap<Class<? extends Component>, ComponentType>(); 

Ho letto su come fare questo con Obj-C, ma non ho avuto successo, la maggior parte delle persone suggeriscono utilizzando un NSDictionary, il problema è che le chiavi devono essere stringhe e li ho bisogno come oggetti. L'altra opzione era NSMapTable, tuttavia non è disponibile su iOS. Qualcuno potrebbe essere d'aiuto su come posso convertirlo in un equivalente obj-c?

grazie,

risposta

21

Le chiavi per un NSDictionary non devono essere stringhe. Possono essere qualsiasi oggetto che implementa NSCopying. Se l'oggetto è un oggetto personalizzato, tuttavia, è necessario produrre risposte sensate ai messaggi -hash e -isEqual:, ma questo è lo stesso che utilizzare un oggetto in una raccolta Java, quindi non dovrebbe essere una grande sfida.

7

si desidera utilizzare un NSDictionary. Lei dice che

essi chiavi devono essere stringhe e ho bisogno di loro come oggetti

le chiavi di un NSDictionary non hanno bisogno di essere stringhe - possono essere qualsiasi oggetto che è conforme alla Protocollo NSCopying.

+2

Questo è corretto. Si noti che esiste una situazione comune in cui 'NSDictionary' * necessita * di chiavi stringa: se si prevede che il' NSDictionary' venga utilizzato in un Elenco proprietà. –

3

Da NSDictionary reference

Una coppia chiave-valore all'interno di un dizionario si chiama una voce. Ogni voce è composta da un oggetto che rappresenta la chiave e un secondo oggetto che rappresenta il valore di tale chiave. All'interno di un dizionario, i tasti sono unici. Cioè, non esistono due chiavi in ​​un singolo dizionario uguali (come determinato da isEqual :). In generale, una chiave può essere qualsiasi oggetto (a condizione che sia conforme al protocollo NSCopying - vedi sotto), ma si noti che quando si utilizza la codifica del valore-chiave, la chiave deve essere una stringa (vedere "Nozioni fondamentali sulla codifica dei valori-chiave"). Né una chiave né un valore possono essere nulli; se è necessario rappresentare un valore nullo in un dizionario, è necessario utilizzare NSNull.

Quindi qualsiasi oggetto che soddisfi il protocollo NSCopying può essere utilizzato come chiave.La restrizione della stringa è solo per valore-chiave di codifica utilizzato per gli attacchi di cacao

15

Un NSMutableDictionary (partendo dal presupposto che è necessario anche impostare i valori nel dizionario dopo la sua inizializzazione) funziona in due modi:

  1. Come dizionario tradizionale/hashmap in cui è possibile impostare i valori in questo modo:

    [myDictionary setObject: theValue forKey: anyObject];

  2. come un oggetto con KVC-compliant proprietà che capita di essere definiti in modo dinamico:

    [myDictionary setValue: theValue forKey: aString];

Se la chiave è un NSString, poi i due sono intercambiabili, con l'eccezione che non è possibile impostare un oggetto per nil con setObject:forKey:, ma si può passare nil-setValue:forKey:.

1

Suppongo che si stia utilizzando una chiave non conforme al protocollo NSCopying. In tal caso, provare a utilizzare l'equivalente Core Foundation di NSDictionary: CFDictionary.

http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html

Basta fare in modo che quando si utilizza CFDictionary che tutti gli oggetti stanno per essere conservati nella memoria per tutta la durata dell'oggetto. Poiché CFDictionary deve essere impostato con riferimenti deboli (almeno nella mia esperienza), fai attenzione che non accidentalmente dealloc uno dei tuoi oggetti mentre è ancora nel CFDictionary.

Mentre CFDictionary è "a pagamento senza pedaggio" con la sua controparte Cocoa Foundation, NSDictionary, trovo che ci sono ancora problemi con questo. Ho provato ad aggiungere oggetti che non facevano parte del protocollo NSCopying al mio NSDictionary con ponte gratuito e ha generato un errore in fase di esecuzione.

docs CFDictionary: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html

Se avete bisogno di mutevolezza, utilizzare CFMutableDictionary invece in questo modo: CFD = CFDictionaryCreateMutable (NULL, 0, NULL, NULL); CFDictionaryAddValue (cfd, chiave, valore); CFRelease (cfd);

docs CFMutableDictionary: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFMutableDictionaryRef/Reference/reference.html#//apple_ref/doc/uid/20001497

+0

Ciao, grazie per tutte le risposte. Se sto usando ARC e utilizzo un CFDictionary, devo ancora gestire la memoria? – Black20

+0

Se si utilizza ARC con CFDictionary, sarà necessario gestire la memoria a meno che non si decida di utilizzare il bridging gratuito. Personalmente non sono riuscito a far funzionare correttamente il brosking per me dal momento che continuava a cercare di copiare oggetti non conformi a NSCopying – bendu

+0

Ecco ulteriori informazioni sull'argomento scorrere verso il basso fino alla parte sul bridging gratuito http://developer.apple. com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html # // apple_ref/doc/uid/TP40011226-CH1-DontLinkElementID_5 – bendu