>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 является изменяемым, хотя из его названия это и не следует.
Обеспечение поддержки подписывания объектов в ваших классах
Традиционно при необходимости доступа к объектам, содержащимся в коллекциях – например, массивах и словарях, – программисту требовалось получить доступ к методу в словаре или массиве, чтобы получить или установить желаемый объект. Например, создавая изменяемый словарь, мы добавляем в него два ключа и значения, получая эти значения обратно: