iOS. Приемы программирования. Вандад Нахавандипур. Читать онлайн. Newlib. NEWLIB.NET

Автор: Вандад Нахавандипур
Издательство: ""Издательство ""Питер""
Серия: Бестселлеры O’Reilly (Питер)
Жанр произведения: Программирование
Год издания: 2014
isbn: 978-5-496-01016-0
Скачать книгу
нашем файле реализации */

      extern NSString *const kFirstNameKey;

      extern NSString *const kLastNameKey;

      @interface Person: NSObject

      @property (nonatomic, copy) NSString *firstName;

      @property (nonatomic, copy) NSString *lastName;

      – (id) objectForKeyedSubscript:(id<NSCopying>)paramKey;

      – (void) setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey;

      @end

      Метод objectForKeyedSubscript: будет вызываться в вашем классе всякий раз, когда программист предоставит ключ и захочет прочитать в вашем классе значение, соответствующее данному ключу. Очевидно, тот параметр, который будет вам передан, будет представлять собой ключ, по которому программист хочет считать интересующее его значение. Дополнительно к этому методу мы будем вызывать в нашем классе метод setObject: forKeyedSubscript: всякий раз, когда программист захочет задать значение для конкретного ключа. Итак, в данной реализации мы хотим проверить, ассоциированы ли заданные ключи с именами и фамилиями. Если это так, то собираемся установить/получить в нашем классе значения имени и фамилии:

      #import "Person.h"

      NSString *const kFirstNameKey = @"firstName";

      NSString *const kLastNameKey = @"lastName";

      @implementation Person

      – (id) objectForKeyedSubscript:(id<NSCopying>)paramKey{

      NSObject<NSCopying> *keyAsObject = (NSObject<NSCopying> *)paramKey;

      if ([keyAsObject isKindOfClass: [NSString class]]){

      NSString *keyAsString = (NSString *)keyAsObject;

      if ([keyAsString isEqualToString: kFirstNameKey] ||

      [keyAsString isEqualToString: kLastNameKey]){

      return [self valueForKey: keyAsString];

      }

      }

      return nil;

      }

      – (void) setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey{

      NSObject<NSCopying> *keyAsObject = (NSObject<NSCopying> *)paramKey;

      if ([keyAsObject isKindOfClass: [NSString class]]){

      NSString *keyAsString = (NSString *)keyAsObject;

      if ([keyAsString isEqualToString: kFirstNameKey] ||

      [keyAsString isEqualToString: kLastNameKey]){

      [self setValue: paramObject forKey: keyAsString];

      }

      }

      }

      @end

      Итак, в этом коде мы получаем ключ в методе objectForKeyedSubscript:, а в ответ должны вернуть объект, который ассоциирован в нашем экземпляре с этим ключом. Ключ, который получаем, – это объект, соответствующий протоколу NSCopying. Это означает, что при желании мы можем сделать копию такого объекта. Рассчитываем на то, что ключ будет представлять собой строку, чтобы мы могли сравнить его с готовыми ключами, которые были заранее объявлены в начале класса. В случае совпадения зададим значение данного свойства в этом классе. После этого воспользуемся методом valueForKey:, относящимся к объекту NSObject, чтобы вернуть значение, ассоциированное с заданным ключом. Но, разумеется, прежде, чем так поступить, мы должны гарантировать, что данный ключ – один из тех, которые мы ожидаем. В методе setObject: forKeyedSubscript: мы делаем совершенно противоположное – устанавливаем значения для заданного ключа, а не возвращаем их.

      Теперь в любой части вашего приложения вы можете инстанцировать объект типа Person и использовать заранее определенные ключи kFirstNameKey и kLastNameKey, чтобы изменить значения свойств firstName и lastName, вот так:

      Person *person = [Person new];

      person[kFirstNameKey] = @"Tim";

      person[kLastNameKey] = @"Cook";

      __unused NSString *firstName = person[kFirstNameKey];

      __unused NSString *lastName = person[kLastNameKey];

      Этот