Как использовать NSEnumerator для обхода NSDictionary

Пример:
        NSDictionary *theDomains = [NSDictionary dictionaryWithObjectsAndKeys:
              @"Россия", @"ru"
            , @"Соединенные Штаты Америки", @"us"
            , @"Китай", @"cn"
            , @"Индия", @"in"
            , @"Бразилия", @"br"
            , @"Иран", @"ir"
            , @"Великобритания", @"uk", nil];
        NSEnumerator *theKeyEnumerator = [theDomains keyEnumerator];
        NSEnumerator *theObjectEnumerator = [theDomains objectEnumerator];
        NSString *theDomain;
        while (theDomain = [theKeyEnumerator nextObject])
        {
            NSString *theCountry = [theObjectEnumerator nextObject];
            NSLog(@"%@ - %@", theCountry, theDomain);
        }

Результат исполнения:
2015-03-19 03:37:32.822 CommandLineTool[5916:303] Китай - cn
2015-03-19 03:37:32.824 CommandLineTool[5916:303] Индия - in
2015-03-19 03:37:32.825 CommandLineTool[5916:303] Соединенные Штаты Америки - us
2015-03-19 03:37:32.825 CommandLineTool[5916:303] Великобритания - uk
2015-03-19 03:37:32.826 CommandLineTool[5916:303] Россия - ru
2015-03-19 03:37:32.826 CommandLineTool[5916:303] Иран - ir
2015-03-19 03:37:32.827 CommandLineTool[5916:303] Бразилия - br

Как видно порядок указанный при инициализации и порядок при обходе различаются. Но это естественно, ведь используется структура данных "словарь" и порядок тут не важен.

В примере выше хватило бы одного keyEnumerator, а получить соответствующий ключу объект можно было бы например так:
        NSEnumerator *theKeyEnumerator = [theDomains keyEnumerator];
        NSString *theDomain;
        while (theDomain = [theKeyEnumerator nextObject])
        {
            NSString *theCountry = theDomains[theDomain];
            NSLog(@"%@ - %@", theCountry, theDomain);
        }

Или так:
            NSString *theCountry = [theDomains objectForKey:theDomain];


Можно ещё пару слов сказать об методе инициализации dictionaryWithObjectsAndKeys:, данный метод работает пока не встретит nil. Поэтому если переменная-ключ окажется nil, то вы получите ошибку, а если переменная-значение окажется nil, то создание словаря закончится в этом месте. В примере выше инициализация проводится литералами, но в реальном коде вы можете использовать переменные и незнание этого нюанса может привести к недопониманию.