Язык Objective-C предоставляет средство для перевода строки в вызов метода доступа, которое называется кодированием ключ-значение (key-value coding).

Такой перевод полезен, например, когда имя требуемого метода доступа не известно заранее, до времени выполнения.

Строка является ключом. Эквивалентом вызова метода доступа для получения значения переменной экземпляра в кодировании ключ-значение является вызов метода valueForKey:; эквивалентом вызова метода доступа для установки значения переменной экземпляра является вызов setValue:fогКеу:.

Таким образом, предположим, например, что мы хотим вызвать метод number экземпляра fido. Это можно сделать с помощью отправки сообщения valueForKey: экземпляру fido с ключом @ "number". Однако, несмотря на то, что метод number возвращает значение типа int, значение, возвращаемое методом valueForKey:, является объектом — в данном случае это объект класса NSNumber, эквивалентный числу (см. главу 10). Если нам нужен реальный экземпляр типа int, то можно воспользоваться методом экземпляра intValue класса NSNumber, который позволяет получить это число:

NSNumber* num « [fido valueForKey: @Mnumber"];
int n ш [num intValue];

Аналогично, чтобы использовать кодирование ключ-значение для вызова метода setNumber: экземпляра fido, мы должны воспользоваться кодом

NSNumber* num = [NSNumber numberWithInt:42];
[fido setValue: num forKey: @"numberM];

Перед передачей числа 42 в качестве значения аргумента setValue: forKey: мы должны “завернуть” его в объект, в данном случае — в объект NSNumber. Начиная с версии компилятора LLVM 4.0 (Xcode 4.4) для этого имеется синтаксическое сокращение; так же как мы можем создавать NSString, помещая текст в директиву компилятора 0" ... ", мы можем создать и NSNumber, помещая числовое выражение в директиву компилятора @ (...); или, если числовое выражение является просто литералом, перед ним можно поставить символ Так что предыдущий пример может быть переписан следующим образом:

NSNumber* num = @42;
[fido setValue: num forKey: @"number"];
<

В реальном программировании вы, вероятно, предпочтете опустить промежуточную переменную num и запишете весь код как одно выражение:

[fido setValue: @42 forKey: @"number"];

В этих примерах нет никакого преимущества применения кодирования ключ-значение перед вызовом методов доступа. Предположим, что мы получили значение number" в переменной (скажем, как результат вызова метода). Пусть эта переменная имеет имя something. Тогда мы можем написать

id result = [fido valueForKey: something];

Таким образом, мы можем обратиться в разных ситуациях к разным методам доступа. Такая гибкость возможна благодаря тому, что Objective-C настолько динамический язык программирования, что отправляемое объекту сообщение оказывается не сформировано до реального выполнения программы.

Когда вы вызываете valueForKey: или setValue : forKey:, вызывается корректный метод доступа, если таковой имеется. Таким образом, когда в качестве ключа мы используем @ "number", вызываются методы number и setNumber: (если таковые существуют). Это одна из причин, по которой ваши методы доступа должны иметь корректные имена. С другой стороны, если метода доступа не существует, но есть переменная экземпляра с тем же именем, что и ключ, будет выполнено непосредственное обращение к этой переменной (даже если ее имя начинается с подчеркивания)! Такое непосредственное обращение нарушает закрытость переменных экземпляров, так что имеется способ отключения этой возможности для определенных классов, если вы не хотите предоставления такого доступа. (Более подробно на эту тему мы поговорим в главе 12.)


 

 

 

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


Защитный код
Обновить