2010-01-28 9 views
1

J'utilise NSDictionary en tant que tableau associé (par exemple, les clés que j'utilise peuvent être des objets arbitraires). L'une des choses les plus agaçantes à propos de NSDictionary est qu'il fait toujours une copie de la clé et la stocke. Dans mon scénario, je récupérerai plus tard les clés du NSDictionary et ferai quelques opérations avec elles. L'opération dépend de l'identité de l'objet des clés. Parce que les clés que j'ai récupérées plus tard sont des copies des objets que j'ai initialement utilisés comme clés. La vérification d'identité d'objet ultérieure échoue.Un NSDictionary qui ne copie pas les clés pour le SDK iPhone 3.0?

Ma question est, y a-t-il une structure de données de type hashtable dans le SDK iPhone 3.0 qui ne copie pas les clés? Je vous remercie.

Outdateboy

Répondre

2

Si vous ne voulez pas que votre clé à copier (ou même conservé), vous pouvez utiliser CFDictionary et fournir un kCFTypeDictionaryKeyCallbacks ou NULL ou personnalisés callbacks clés.

Pour vérifier si les objets sont égaux, vous devez utiliser -isEqual: au lieu de ==.

+0

Et si vous comparez des objets de votre classe, vous implémentez simplement votre propre méthode -isEqual dans la classe. –

+0

Pourquoi utiliser les rappels 'NULL'? Utilisez juste 'kCFTypeDictionaryKeyCallBacks' (conserver les clés) au lieu de' kCFCopyStringDictionaryKeyCallBacks' (clés de copie). –

+0

@Peter: 'kCFCopyStringDictionaryKeyCallBacks' n'est pas utilisé du tout dans' NSDictionary' donc je suppose que la préoccupation du demandeur n'est pas simplement de copier. – kennytm

1

NSDictionary est un pont gratuit avec CFDictionary. Donc juste faire:

CFDictionarySetValue((CFDictionaryRef)myMutableDict, key, object); 

C'est seulement la méthode Cocoa qui copie la clé.

+1

Je ne compterais pas sur NSMutableDictionaries-as-CFMutableDictionaries n'utilisant pas les rappels de chaîne de copie. La documentation ne définit pas explicitement (pour autant que je puisse trouver) ce qui se passe quand vous faites cela, mais si quelque chose, je considérerais cela comme un bug. –

+0

Je suppose que c'est difficile à savoir; les docs ne sont pas très clairs. Je vais sur une combinaison de "ça a toujours été comme ça" et que les docs déclarent que toutes les * méthodes * pour placer des objets dans un dictionnaire vont copier la clé. –

1

J'ai récemment fait ce qui suit pour obtenir un MutableDictionary qui ne copie pas ses clés.

-(NSMutableDictionary*)mutableDictionaryWithRetainedKeys { 
    CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
    return CFBridgingRelease(dictionary); 
} 

Si vous êtes clés ne respectent pas NSCopying et vous voulez éviter les avertissements du compilateur lors de la définition des valeurs clés/utilisation:

CFDictionarySetValue(dictionary, (__bridge const void *)(key), (__bridge const void *)(value)); 
+0

essayez ceci: Prenez le 'NSMutableDictionary' qui est retourné par cette méthode, faites un' setObject: forKey: 'dessus avec une clé d'une classe personnalisée et mettez un point d'arrêt sur' -copyWithZone: '; vous verrez qu'il s'appelle. Faites maintenant 'setObject: forKey:' avec une clé d'une classe personnalisée qui n'implémente pas '-copyWithZone:' (ignore les avertissements); vous verrez qu'il lance une exception. – user102008

+1

Oui, vous avez raison. Merci. Vous devez utiliser 'CFDictionarySetValue' pour éviter d'appeler' -copyWithZone: '. –