Вандад Нахавандипур

iOS. Приемы программирования


Скачать книгу

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

      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 не останавливается и на этом. Вы можете также добавлять подписывание и к собственным классам. Существует два типа подписывания:

       подписывание по ключу – действуя таким образом, вы можете задавать внутри объекта значение для того или иного ключа точно так же, как вы делали бы это в словаре. Указывая ключ, вы также можете получать доступ к значениям внутри объекта и считывать их;

      • подписывание по индексу – как и при работе с массивами, вы можете устанавливать/получать значения внутри объекта, предоставив для этого объекта индекс. Это целесообразно делать в массивоподобных классах, где элементы естественным образом располагаются в порядке, удобном для индексирования.

      Сначала рассмотрим пример подписывания по ключу. Для этого создадим класс под названием Person, имеющий свойства firstName и lastName. Далее мы позволим программисту менять