AppController.h:
@interface AppController : NSObject
{
int fido;
}
@property (readonly, assign) int fido;
@end
импорт "AppController.h"
@implementation AppController
@synthesize fido;
...
@end
На этом этапе вы объявили, что AppController имеет метод -fido
, и вы синтезировали этот метод. Нет -setFido:
метода. Итак, почему следующее «работает»?
- (id)init
{
if (self=[super init]) {
[self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
NSNumber *n = [self valueForKey:@"fido"];
NSLog(@"fido = %@", n);
}
return self;
}
(Кстати: я исправил ваш -init для реализации правильного шаблона)
Это работает, потому что KVC следует эвристический , чтобы установить или получить значение. Вызов -setValue:forKey:
сначала ищет -setFoo:
. Если он не найден, он ищет переменную экземпляра foo
и устанавливает ее напрямую.
Обратите внимание, что если вы измените переменную экземпляра fido
на _fido
, набор будет работать, но valueForKey
вернет 0 при вызове синтезированного метода (поскольку я на 64-битной, @synthesize синтезирует переменную экземпляра fido
. Я знаю, что сбивает с толку.).
Если бы вы изменили имя своего ивара на bar
, а затем использовали @synthesize foo=bar;
, код потерпел бы неудачу во время выполнения.
Вы увидите:
2009-10-01 08:59:58.081 dfkjdfkjfjkfd[24099:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppController 0x20000e700> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key fido.'
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff85b055a4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff85c5a0f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff85b5caf9 -[NSException raise] + 9
3 Foundation 0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
(
0 CoreFoundation 0x00007fff85b055a4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff85c5a0f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff85b5caf9 -[NSException raise] + 9
3 Foundation 0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
4 dfkjdfkjfjkfd 0x0000000100000d96 -[AppController init] + 130