Механизм доступа к значениям по ключам позволяет реализовать в объекте ключ таким образом, как будто его значением является массив (или множество), даже если это на самом деле не так.

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

- (NSUInteger) countOfPepBoys {

return [self.theData count];

}

- (id) objectlnPepBoysAtlndex:        (NSUInteger)        ix {

return (self.theData)[ix];

}

Благодаря реализации методов типа countOf. . . и objectln. . .Atlndex: механизму доступа к значениям по ключам предписывается действовать таким образом, как будто заданный ключ (в данном случае — 0"pepBoys") существует и является массивом. Попытка извлечь значение ключа 0"pepBoys" с помощью механизма доступа к значениям по ключам будет успешной, а в итоге возвратится объект, который можно рассматривать как массив, хотя на самом деле это объект-заместитель (класса NSKeyValueArray). Итак, теперь можно сделать вызов [myObject valueForKey: 0"pepBoysn], чтобы получить этот объект-заместитель массива, а также вызов [myObject valueForKeyPath: 0 "pepBoys . name" ], чтобы получить такой же массив символьных строк, как и прежде.

 

Приведенный выше конкретный пример может показаться несколько простоватым, поскольку в его основу уже положена реализация переменной экземпляра массива. Но нетрудно представить и такую реализацию, где результат вызова метода obj ectlnPepBoysAtlndex: получается с помощью операции совершенно другого рода.

Объект-заместитель, возвращаемый через подобный фасад, ведет себя как объект типа NSArray, а не типа NSMutableArray. Если требуется предоставить вызывающему коду возможность манипулировать объектом-заметителем, предоставляемым фасадом механизма KVC, как будто это изменяемый массив, то придется реализовать еще два метода, а вызывающий код должен получить другой объект-заместитель, вызвав метод mutableArrayValueForKey:. Ниже приведен пример реализации таких методов; при этом предполагается, что theData — это изменяемый массив.

- (void) insertObject:          (id)          val           inPepBoysAtlndex:             (NSUInteger)        ix             (

[self.theData insertObject:val atlndex:ix];

}

- (void) removeObjectFromPepBoysAtlndex:              (NSUInteger)        ix             {

[self.theData removeObjectAtlndex: ix];

)

Теперь можно сделать вызов [myObject mutableArrayValueForKey: 0"pepBoys"]> чтобы получить нечто похожее на изменяемый массив. (Истинная польза от метода mutableArrayValueForKey: станет яснее, когда речь пойдет о механизме наблюдения за значениями по ключам в главе 13.)

Трудности для программирования состоят в том, что ни один из этих методов невозможно найти непосредственно в документации, поскольку в их именах указываются ключи, характерные для конкретного объекта. В частности, из документации нельзя выяснить, для чего предназначен метод removeOb j ectFromPepBoysAtlndex:. Для этого нужно узнать каким-то другим способом, что данный метод является частью реализации соответствия механизму доступа к значениям по ключу @"pepBoys", который может быть получен в качестве изменяемого массива. В связи с этим рекомендуется непременно снабжать прикладной код комментариями, чтобы его можно было понять в дальнейшем.

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


 

 

 

Добавить комментарий