2010-11-19 31 views
4

Je comprends que la bonne façon de trier un NSDictionary est de créer un tableau à partir des clés, de trier le tableau, puis d'énumérer le tableau et d'opérer sur le NSDictionary à partir de là. Ma question est, pour un NSDictionary * dict, avec les touches et les valeurs des chaînes,Pourquoi NSDictionary est-il alphabétique en mémoire, mais pas en énumération?

Pourquoi cette alphabétique:

NSLog(@"%@", dict); 

Mais ce n'est pas:

for (NSString *w in dict) 
{ 
    NSLog(@"%@", w); 
} 

... semble étrange Est-ce que je fais quelque chose de mal?

Merci d'avance.

Répondre

6

Ce n'est pas "en mémoire" -% @ provoque l'appel d'un message sur dict, et cela l'a trié. L'énumération est destinée à vous donner l'accès brut le plus rapide au contenu. Si vous en avez besoin trié, vous devez le trier.

Jetez un oeil à ce dictionnaire libre triés pour Objective-C

http://code.google.com/p/cocoa-sorted-dictionary/

+0

Ah, c'est logique. Je n'ai pas pensé au% @ de NSLog pour faire le tri. Merci! – iBuys

+0

I.e. les dictatures sont intrinsèquement non ordonnées. – bbum

+0

Un dictionnaire est juste une interface pour une collection qui mappe une valeur à une autre. Il ne doit pas être non ordonné. Par exemple, je pourrais faire un dictionnaire sur un arbre binaire - dans ce cas, il serait commandé. En C++, std :: map a une interface de dictionnaire, et est ordonnée. Une table de hachage est non ordonnée, donc un dictionnaire fait à partir de l'un serait aussi. –

2

Parce que la première trie le tableau exactement de la façon que vous décrivez, pour le rendre plus facile pour l'utilisateur/programmeur pour trouver des trucs. Cependant, vous obtiendrez l'ordre d'itération si vous utilisez le niveau inférieur CFCopyDescription(dict).

Le code source des collections CoreFoundation est available, bien que sans l'interface Objective-C. NSDictionary/CFDictionary et NSSet/CFSet sont basées sur CFBasicHash, ce qui implémente sans surprise une table de hachage. CFCopyDescription() et boucle d'itération rapide sur les éléments dans l'ordre de la mémoire (CFBasicHashApply() et CFBasicHashGetBucket() dans CFBasicHash.m). La commande réelle est conçue pour une recherche rapide basée sur le hachage. Si vous n'êtes pas familier avec les tables de hachage, voir Wikipedia.

+0

Ceci est une bonne explication aussi, merci pour l'information en profondeur. – iBuys