ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

NSDictionary (словари)

Словари делают код программы более выразительным…

Хочу начать эту статью с небольшого кусочка кода:

<code data-result="[object Object]">NSArray *girls = [NSArray arrayWithObjects:@"Amanda", @"Ira", @"Natali", nil];
NSArray *boys = [NSArray arrayWithObjects:@"Sergei", @"Vova", @"Ivan", nil];
NSArray *children = [NSArray arrayWithObjects:girls, boys, nil];
NSLog(@"girls: %@", [children objectAtIndex:0]);
NSLog(@"boys: %@", [children objectAtIndex:1]);</code>

На первый взгляд — это самый обычный код. Мы создаем два массива (девочки и мальчики). Затем создаем третий массив, в который помещаем первые два. Все просто и доступно. Но так ли это? На самом деле этот код не выразителен. Представьте, что перед нами стоит задача хранить имена клиентов магазина, а эти клиенты разбиты на 10 групп. Соответственно для реализации этой задачи нам нужно 11 массивов (по одному на каждую группу и один, в котором будут храниться все группы). Таким образом — нам прийдется запомнить под каким индексом какой массив мы храним. Вам покажется, что проблему можно решить комментариями. Но если над программой работаем не только мы и кто-то из программистов решит изменить порядок хранения массивов, а комментарий (как это обычно бывает) — не изменит. Такой комментарий не только бесполезен, он является источником дезинформации.

Класс NSDictionary придает выразительности нашему коду. Фактически это тот же самый массив, только вместо индексов мы используем ключи (keys).

<code data-result="[object Object]">NSArray *girls = [NSArray arrayWithObjects:@"Amanda", @"Ira", @"Natali", nil];
NSArray *boys = [NSArray arrayWithObjects:@"Sergei", @"Vova", @"Ivan", nil];
NSDictionary *children = [NSDictionary dictionaryWithObjectsAndKeys:girls, @"girls", 
boys, @"boys", nil];
NSLog(@"girls: %@", [children objectForKey:@"girls"]);
NSLog(@"boys: %@", [children objectForKey:@"boys"]);</code>

В этом примере мы так же создаем два массива, только затем мы их добавляем в словарь, под ключами (в ключах мы храним имена массивов). Затем по этим ключам мы можем обращаться к нашим массивам.

Для более детального рассмотрения возможностей NSDictionary создадим новый проект на основе представления (View-based Application) и назовем его Dictionaries. Теперь откройте файл DictionariesViewController.m, раскомментируйте в нем методviewDidLoad и добавьте в него следующий код:

<code data-result="[object Object]">NSDictionary *d1 = [NSDictionary dictionary];
NSDictionary *d2 = [NSDictionary dictionaryWithObject:@"Bill" forKey:@"name"];
NSDictionary *d3 = [NSDictionary dictionaryWithDictionary:d2];</code>

В первой строчке этого кода мы создаем пустой словарь. Во второй — словарь с объектом @»Bill» под ключом @»name». В третьей строчке мы создаем словарь используя уже имеющийся словарь.

Ключи и значения, которые мы хотим поместить в словарь можно хранить в массивах. Следующий код демонстрирует эту возможность.

<code data-result="[object Object]">NSArray *theObjects = [NSArray arrayWithObjects:@"Bill", [NSNumber numberWithInt:32], nil];
NSArray *theKeys = [NSArray arrayWithObjects:@"name", @"age", nil];
NSDictionary *d4 = [NSDictionary dictionaryWithObjects:theObjects forKeys:theKeys];
NSLog(@"%@", d4);</code>

В первом массиве мы храним объекты, а во втором — их ключи. Затем, используя метод dictionaryWithObjects мы создаем словарь, а в качестве параметров — передаем эти массивы. В результате мы получим следующий код:

2011-03-18 23:42:09.507 Dictionaries[1147:207] {

    age = 32;

    name = Bill;

}

Следующий код еще раз демонстрирует работу метода dictionaryWithObjectsAndKeys, пример которого я приводил в начале статьи.

<code data-result="[object Object]">NSDictionary *d5 = [NSDictionary dictionaryWithObjectsAndKeys:
                    @"Bill", @"name",
                    [NSNumber numberWithInt:32], @"age", 
                    nil];
NSLog(@"%@", d5);</code>

Результат работы этого кода будет эквивалентным предыдущему результату. Здесь главное запомнить последовательность (ключ следует за своим объектом). То есть: объект ⇔ ключ, объект ⇔ ключ (стрелками я обозначил принадлежность ключа объекту, в реальном коде их следует заменить запятыми).

Метод count знаком нам с класса NSArray возвращает количество записей словаря.

<code data-result="[object Object]">NSInteger count = [d5 count];
NSLog(@"%i", count);</code>

Так же у нас есть возможность сравнивать два словаря.

<code data-result="[object Object]">BOOL equal = [d5 isEqualToDictionary:d4];
NSLog(@"Equal? %i", equal);</code>

Метод allKeys возвратит нам массив всех ключей, которые имеет наш словарь.

<code data-result="[object Object]">NSArray *keys = [d4 allKeys];
NSLog(@"Keys: %@", keys);</code>

А метод allValues возвратит массив всех значений:

<code data-result="[object Object]">NSArray *values = [d5 allValues];
NSLog(@"Values: %@", values);</code>

Так же как и в случае с массивом, если мы не знаем тип объекта, который храниться в словаре — ему следует указать тип id.

<code data-result="[object Object]">id obj = [d5 objectForKey:@"name"];
NSLog(@"Value for name is %@", obj);</code>

В этом примере мы по ключу получаем значение объекта, хранящегося в словаре и выводим его в консоль. Я думаю, что на этом можно остановиться. Если кто-то так не считает — пишите в комментариях и я дополню статью.

 

Исходный код можно скачать здесь.

Comments are closed.