iOS. Приемы программирования - страница 16



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

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

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

Чтобы обеспечить поддержку подписывания по ключу в ваших собственных классах, вы должны реализовать в вашем классе два следующих метода и записать сигнатуры методов в файле заголовков этого класса. В противном случае компилятор не узнает, что в вашем классе поддерживается подписывание по ключу.


>#import 


>/* Мы будем использовать их как ключи для наших свойств firstName

>и lastName, так что если имена наших свойств firstName и lastName

>в будущем изменятся в реализации, нам не придется ничего переделывать

>и наш класс останется работоспособным, поскольку мы сможем просто

>изменить значения этих констант в нашем файле реализации */

>extern NSString *const kFirstNameKey;

>extern NSString *const kLastNameKey;


>@interface Person: NSObject


>@property (nonatomic, copy) NSString *firstName;

>@property (nonatomic, copy) NSString *lastName;


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

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


>@end


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


>#import "Person.h"


>NSString *const kFirstNameKey = @"firstName";

>NSString *const kLastNameKey = @"lastName";


>@implementation Person


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


>NSObject *keyAsObject = (NSObject *)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)paramKey{