Ответь себе. valueForKey:
словаря перезаписывает поведение по умолчанию, если в словаре нет ключа, он вернет nil и не вызовет метод доступа, как NSObject
, как говорится в документе Apple:
Если ключ не начинается с «@», вызывает objectForKey :. Если ключ
начинается с «@», удаляет «@» и вызывает [super valueForKey:] с
остальная часть ключа.
Поскольку NSDictionary
является кластерным классом, не рекомендуется использовать подкласс для перезаписи поведения. Вместо этого я использую метод швейцарский, как это:
@implementation NSDictionary (MyAddition)
static void swizzle(Class c, SEL orig, SEL new)
{
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
}
+ (void)initialize
{
if (self == [NSDictionary class]){
swizzle([NSDictionary class],
@selector(valueForKey:),
@selector(myValueForKey:));
}
}
- (id)toMyObject
{
return toMyObject;
}
...
- (id)myValueForKey:(NSString *)key
{
// for collection operators
if ([key compare:@"@" options:0 range:NSMakeRange(0, 1)] == NSOrderedSame)
return [super valueForKey:key];
if ([key isEqualToString:@"toMyObject"])
return [self toMyObject];
return [self myValueForKey:key];
}
Теперь NSArray безопасно вызывать valueForKey:@"toMyObject"
.