2013-08-03 2 views
9

Я пытаюсь научить себя объективному c использованием большой книги ранчо ранчо, это действительно отличная книга, но некоторые аспекты меня смущают.Objective-C setValue: forKey on c примитивные типы

В текущей главе говорится об использовании функции setValue: forKey, которую я понимаю, является методом, определенным в NSObject. В книге говорится, что вы можете использовать это на переменном токе примитивного как межды или поплавок, и дает этому примеру

У меня есть пользовательский класс под названием Appliance и в нем является переменным экземпляром целого, называемое напряжением, которое хранит напряжение из ток прибора я инициализировать новый прибор, называемый

appliance *a = [[appliance alloc]init]; 
[a setValue:[NSNumber numberWithInt:240] forKey:@"voltage"]; 

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

-(void)setVoltage:int(x) { 
NSLog(@"setting voltage to %d",x); 
voltage =x; 
} 

Что меня пугает: NSNumber numberWithInt возвращает указатель на объект NSNumber, который хранится в куче правильно? поэтому как он регистрирует целое число, хранящееся в NSNumber, используя токен% d. Я понимаю, что будет записывать целое число, но не является объектом, который передается? кроме того, я думал, что, поскольку напряжение было определено как целое, а не указатель на что-то, что оно не могло удерживать адрес в объекте в его памяти? или NSNumber, заставляя его хранить свой адрес памяти без фактического объявления напряжения в качестве указателя?

извините за путаницу, эта глава в основном пнула мою задницу.

+3

Обратите внимание, что в обычных правилах кодирования вы бы никогда не использовали 'setValue: forKey:' или 'valueForKey:' для установки/получения значений на объекте *. Просто вызовите setter/getter напрямую. KVC в основном существует для поддержки таких вещей, как привязки и другие формы метапрограммирования. – bbum

ответ

25

Преобразование объектов и скалярных типов осуществляется автоматически с помощью методов кодирования по значению ключа. Из documentation:

реализации по умолчанию valueForKey: и setValue:forKey: обеспечивают поддержку автоматического объекта оборачивать данных необъектных типов, как скаляры и структуры.

После того, как valueForKey: определил конкретный метод доступа или переменную экземпляра, которая используется для подачи значения для указанного ключа , он проверяет тип возвращаемого или тип данных. Если возвращаемое значение не является объектом, то создается NSNumber или NSValue объект за это значение и возвращается на его место.

Аналогичным образом, setValue:forKey: определяет тип данных, требуемый соответствующей переменной доступа или переменной экземпляра для указанного ключа. Если тип данных не является объектом, то значение извлекается из переданного объекта с использованием соответствующего метода -<type>Value.

Так что в вашем случае, intValue автоматически применяется к переданному NSNumber объекта, и в результате целое число передается setVoltage:.

4

Вы правы в том, что вы создаете экземпляр NSNumber и передаете его. Но вы передаете его до setValue:forKey:, и это делает для вас определенную работу.Он находит подходящий метод setter для voltage (setVoltage:), проверяя тип данных и распаковывая номер в int перед вызовом setter.

Смежные вопросы