KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Вандад Нахавандипур - iOS. Приемы программирования

Вандад Нахавандипур - iOS. Приемы программирования

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Вандад Нахавандипур, "iOS. Приемы программирования" бесплатно, без регистрации.
Перейти на страницу:

Хранение элементов в коллекциях и получение элементов из коллекций

Коллекции — это такие объекты, в экземплярах которых могут храниться другие объекты. Одна из самых распространенных разновидностей коллекций — это массив, который инстанцирует NSArray или NSMutableArray. В массиве можно хранить любой объект, причем массив может содержать несколько экземпляров одного и того же объекта. В следующем примере мы создаем массив из трех строк:


NSArray *stringsArray = @[

@"String 1",

@"String 2",

@"String 3"

];


__unused NSString *firstString = stringsArray[0];

__unused NSString *secondString = stringsArray[1];

__unused NSString *thirdString = stringsArray[2];

Макрос __unused приказывает компилятору «не жаловаться», когда переменная — в нашем случае переменная firstString — объявлена, но ни разу не использовалась. По умолчанию в такой ситуации компилятор выдает в консоль предупреждение, сообщающее, что переменная не используется. В нашем кратком примере мы объявили переменные, но не задействовали их. Поэтому, если добавить вышеупомянутый макрос в начале объявления переменной, это вполне устроит и нас, и компилятор.

Изменяемый массив — это такой массив, в который можно вносить изменения уже после того, как он был создан. Как мы видели ранее, неизменяемый массив не может быть дополнен новой информацией уже после создания. Вот пример неизменяемого массива:


NSString *string1 = @"String 1";

NSString *string2 = @"String 2";

NSString *string3 = @"String 3";


NSArray *immutableArray = @[string1, string2, string3];


NSMutableArray *mutableArray = [[NSMutableArray alloc]

initWithArray: immutableArray];


[mutableArray exchangeObjectAtIndex:0 withObjectAtIndex:1];

[mutableArray removeObjectAtIndex:1];

[mutableArray setObject: string1 atIndexedSubscript:0];

NSLog(@"Immutable array = %@", immutableArray);

NSLog(@"Mutable Array = %@", mutableArray);

Вывод этой программы таков:

Immutable array = (

«String 1»,

«String 2»,

«String 3»

)

Mutable Array = (

«String 1»,

«String 3»

)


Еще одна распространенная коллекция, которая часто встречается в программах для iOS, — это словарь. Словари похожи на массивы, но каждому объекту в словаре присваивается ключ, и по этому ключу вы можете позже получить интересующий вас объект. Рассмотрим пример:


NSDictionary *personInformation =

@{

@"firstName": @"Mark",

@"lastName": @"Tremonti",

@"age": @30,

@"sex": @"Male"

};


NSString *firstName = personInformation[@"firstName"];

NSString *lastName = personInformation[@"lastName"];

NSNumber *age = personInformation[@"age"];

NSString *sex = personInformation[@"sex"];


NSLog(@"Full name = %@ %@", firstName, lastName);

NSLog(@"Age = %@, Sex = %@", age, sex);

А вот и вывод этой программы:

Full name = Mark Tremonti

Age = 30, Sex = Male


Можно также использовать изменяемые словари, которые довольно сильно похожи на изменяемые массивы. Содержимое изменяемого словаря можно изменить после того, как словарь инстанцирован. Пример:


NSDictionary *personInformation =

@{

@"firstName": @"Mark",

@"lastName": @"Tremonti",

@"age": @30,

@"sex": @"Male"

};


NSMutableDictionary *mutablePersonInformation =

[[NSMutableDictionary alloc] initWithDictionary: personInformation];

mutablePersonInformation[@"age"] = @32;


NSLog(@"Information = %@", mutablePersonInformation);

Вывод этой программы таков:

Information = {

age = 32;

firstName = Mark;

lastName = Tremonti;

sex = Male;

}


Еще можно работать с множествами. Множества похожи на массивы, но любой объект, входящий в состав множества, должен встречаться в нем только один раз. Иными словами, в одном множестве не может быть двух экземпляров одного и того же объекта. Пример множества:


NSSet *shoppingList = [[NSSet alloc] initWithObjects:

@"Milk",

@"Bananas",

@"Bread",

@"Milk", nil];


NSLog(@"Shopping list = %@", shoppingList);

Запустив эту программу, вы получите следующий вывод:

Shopping list = {(

Milk,

Bananas,

Bread

)}


Обратите внимание: элемент Milk упомянут в программе дважды, а в множество добавлен всего один раз. Эта черта множеств — настоящее волшебство. Изменяемые множества можно использовать и вот так:


NSSet *shoppingList = [[NSSet alloc] initWithObjects:

@"Milk",

@"Bananas",

@"Bread",

@"Milk", nil];


NSMutableSet *mutableList = [NSMutableSet setWithSet: shoppingList];


[mutableList addObject:@"Yogurt"];

[mutableList removeObject:@"Bread"];

NSLog(@"Original list = %@", shoppingList);

NSLog(@"Mutable list = %@", mutableList);

А вывод будет таким:

Original list = {(

Milk,

Bananas,

Bread

)}

Mutable list = {(

Milk,

Bananas,

Yogurt

)}


Обсуждая множества и коллекции, следует упомянуть еще два важных класса, о которых вам необходимо знать:

NSOrderedSet — неизменяемое множество, учитывающее, в каком порядке в него добавлялись объекты;

• NSMutableOrderedSet — изменяемый вариант вышеупомянутого изменяемого множества.

По умолчанию множества не учитывают, в каком порядке объекты в них добавлялись. Рассмотрим пример:


NSSet *setOfNumbers = [NSSet setWithArray:@[@3, @4, @1, @5, @10]];

NSLog(@"Set of numbers = %@", setOfNumbers);

Запустив эту программу, получим на экране следующий вывод:

Set of numbers = {(

5,

10,

3,

4,

1

)}


Но на самом деле мы наполняли множество элементами в другом порядке. Если вы хотите сохранить правильный порядок, просто воспользуйтесь классом NSOrderedSet:


NSOrderedSet *setOfNumbers = [NSOrderedSet orderedSetWithArray

:@[@3, @4, @1, @5, @10]];


NSLog(@"Ordered set of numbers = %@", setOfNumbers);

Разумеется, вы можете воспользоваться и изменяемой версией упорядоченного множества:

NSMutableOrderedSet *setOfNumbers =

[NSMutableOrderedSet orderedSetWithArray:@[@3, @4, @1, @5, @10]];


[setOfNumbers removeObject:@5];

[setOfNumbers addObject:@0];

[setOfNumbers exchangeObjectAtIndex:1 withObjectAtIndex:2];


NSLog(@"Set of numbers = %@", setOfNumbers);

А вот и результаты:

Set of numbers = {(

3,

1,

4,

10,

0

)}


Прежде чем завершить разговор о множествах, упомяну еще об одном удобном классе, который может вам пригодиться. Класс NSCountedSet может несколько раз содержать уникальный экземпляр объекта. Правда, в нем эта задача решается иначе, нежели в массивах. В массиве может несколько раз присутствовать один и тот же объект. А в рассматриваемом здесь «подсчитываемом множестве» каждый объект появляется в множестве как будто заново, но множество ведет подсчет того, сколько раз объект был добавлен в множество, и снижает значение этого счетчика на единицу, как только вы удалите из этого множества экземпляр данного объекта. Вот пример:


NSCountedSet *setOfNumbers = [NSCountedSet setWithObjects:

@10, @20, @10, @10, @30, nil];


[setOfNumbers addObject:@20];

[setOfNumbers removeObject:@10];


NSLog(@"Count for object @10 = %lu",

(unsigned long)[setOfNumbers countForObject:@10]);


NSLog(@"Count for object @20 = %lu",

(unsigned long)[setOfNumbers countForObject:@20]);

Вывод программы:

Count for object @10 = 2

Count for object @20 = 2

Класс NSCountedSet является изменяемым, хотя из его названия это и не следует.

Обеспечение поддержки подписывания объектов в ваших классах

Традиционно при необходимости доступа к объектам, содержащимся в коллекциях — например, массивах и словарях, — программисту требовалось получить доступ к методу в словаре или массиве, чтобы получить или установить желаемый объект. Например, создавая изменяемый словарь, мы добавляем в него два ключа и значения, получая эти значения обратно:


NSString *const kFirstNameKey = @"firstName";

NSString *const kLastNameKey = @"lastName";


NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];

[dictionary setValue:@"Tim" forKey: kFirstNameKey];

[dictionary setValue:@"Cook" forKey: kLastNameKey];


__unused NSString *firstName = [dictionary valueForKey: kFirstNameKey];

__unused NSString *lastName = [dictionary valueForKey: kLastNameKey];

Но с развитием компилятора LLVM этот код можно сократить, придав ему следующий вид:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*