>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 этот код можно сократить, придав ему следующий вид:
>NSString *const kFirstNameKey = @"firstName";
>NSString *const kLastNameKey = @"lastName";
>NSDictionary *dictionary = @{
>kFirstNameKey: @"Tim",
>kLastNameKey: @"Cook",
>};
>__unused NSString *firstName = dictionary[kFirstNameKey];
>__unused NSString *lastName = dictionary[kLastNameKey];
>Как видите, мы инициализируем словарь, давая ключи в фигурных скобках. Точно так же можно поступать и с массивами. Вот как мы обычно создаем и используем массивы:
>NSArray *array = [[NSArray alloc] initWithObjects:@"Tim", @"Cook", nil];
>__unused NSString *firstItem = [array objectAtIndex:0];
>__unused NSString *secondObject = [array objectAtIndex:1];
>А теперь, имея возможность подписывать объекты, мы можем сократить этот код следующим образом:
>NSArray *array = @[@"Tim", @"Cook"];
>__unused NSString *firstItem = array[0];
>__unused NSString *secondObject = array[0];
Компилятор LLVM не останавливается и на этом. Вы можете также добавлять подписывание и к собственным классам. Существует два типа подписывания:
•подписывание по ключу – действуя таким образом, вы можете задавать внутри объекта значение для того или иного ключа точно так же, как вы делали бы это в словаре. Указывая ключ, вы также можете получать доступ к значениям внутри объекта и считывать их;