fast enumeration for NSDictionary instance ordered by the key

user1046037 picture user1046037 · Dec 16, 2011 · Viewed 8.7k times · Source

Overview

  • I am using fast enumeration to iterate through an NSDictionary instance
  • I expected the NSDictionary instance to be enumerated based on the ascending order of the key but that doesn't seem to be the case

What I want to do:

  • I want to be able iterate through the NSDictionary instance in the ascending order of the key using fast enumeration

Note: Pls see expected output vs actual output

Questions

  1. Am i making a mistake with my implementation ?
  2. Does NSDictionary's fast enumeration guarantee ordering based on keys ?
  3. If not then is there a work around for this and yet use fast enumeration ?

Example

#import<Foundation/Foundation.h>

int main()
{
    system("clear");

    NSDictionary *d1 = nil;

    @autoreleasepool
    {   

        d1 = [[NSDictionary alloc] initWithObjectsAndKeys: @"AAA", [NSNumber numberWithInt:10], 
              @"BBB", [NSNumber numberWithInt:20],               
              @"CCC", [NSNumber numberWithInt:30],               
              nil];
    }   

    for(NSNumber* n1 in d1)     //I expected fast enumeration for NSDictionary to be based on the 
        //ascending order of the key but that doesn't seem to be the case
    {
        printf("key = %p"
               "\t [key intValue] = %i"
               "\t value = %s\n", 
               n1, 
               [n1 intValue], 
               [[d1 objectForKey:n1] UTF8String]);
    }   

    return(0);
}

Expected Output

key = 0xa83      [key intValue] = 10     value = AAA
key = 0x1483     [key intValue] = 20     value = BBB
key = 0x1e83     [key intValue] = 30     value = CCC

Actual Output

key = 0x1e83     [key intValue] = 30     value = CCC
key = 0xa83      [key intValue] = 10     value = AAA
key = 0x1483     [key intValue] = 20     value = BBB

Answer

NSResponder picture NSResponder · Dec 16, 2011
for (NSString *key in [[d1 allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
    id value = [d1 valueForKey:key];
    ...
}