>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];

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

>Person *person = [Person new];

>person.firstName = @"Tim";

>person.lastName = @"Cook";

>__unused NSString *firstName = person.firstName;

>__unused NSString *lastName = person.lastName;


Вы также можете поддерживать и подписывание по индексу – точно как при работе с массивами. Как было указано ранее, это полезно делать, чтобы обеспечивать программисту доступ к объектам, выстраиваемым в классе в некоем естественном порядке. Но, кроме массивов, существует не так уж много структур данных, где целесообразно упорядочивать и нумеровать элементы, чего не скажешь о подписывании по ключу, которое применяется в самых разных структурах данных. Поэтому пример, которым иллюстрируется подписывание по индексу, немного надуман. В предыдущем примере у нас существовал класс Person с именем и фамилией. Теперь мы хотим предоставить программистам возможность считывать имя, указывая индекс 0, а фамилию – указывая индекс 1. Все, что требуется сделать для этого, – объявить методы objectAtIndexedSubscript: и setObject: atIndexedSubscript: в заголовочном файле класса, а затем написать реализацию. Вот как мы объявляем два этих метода в заголовочном файле класса Person:

– (id) objectAtIndexedSubscript:(NSUInteger)paramIndex;

– (void) setObject:(id)paramObject atIndexedSubscript:(NSUInteger)paramIndex;

Реализация также довольно проста. Мы берем индекс и оперируем им так, как это требуется в нашем классе. Ранее мы решили, что у имени должен быть индекс 0, а у фамилии – индекс 1. Итак, получаем индекс 0 для задания значения, присваиваем значение имени первому входящему объекту и т. д.:


>– (id) objectAtIndexedSubscript:(NSUInteger)paramIndex{


>switch (paramIndex){

>case 0:{

>return self.firstName;

>break;

>}

>case 1:{

>return self.lastName;

>break;

>}

>default:{

>[NSException raise:@"Invalid index" format: nil];

>}

>}


>return nil;

>}


>– (void) setObject:(id)paramObject atIndexedSubscript:(NSUInteger)paramIndex{

>switch (paramIndex){