Переопределение Objective C valueForKey: из NSMutableDictionary - PullRequest
0 голосов
/ 21 апреля 2011

Мне нужно переопределить valueForKey: метод NSMutableDictionary. Я хочу проверить определенное значение, выполнить некоторые манипуляции и вернуть его. Есть ли какие-то моменты, о которых мне следует знать? Пожалуйста, исправьте меня, если что-то не так, например:

- (id)valueForKey:(NSString*)key {

    id val = [super valueForKey:key];
    if([val isKindOfClass:[NSString class]] && [val isEqualToString:@"<null>"]) {
        return @"No Value";
    }
    else {
        return val;
    }

}

Спасибо

Ответы [ 3 ]

8 голосов
/ 21 апреля 2011

Вы, вероятно, не хотите переопределять valueForKey, потому что NSDictionary и NSMutableDictionary являются абстрактными базовыми классами, скрывающими кластер классов за ними.Согласно их документации, в прямом подклассе вам необходимо переопределить все:

  • setObject: forKey:
  • removeObjectForKey:
  • count
  • objectForKey:
  • keyEnumerator

Проще реализовать альтернативный класс, который претендует на то, чтобы быть NSMutableDictionary, но перенаправляет любые вызовы, которые он не понимает, на фактический NSMutableDictionary.Что вы можете сделать с помощью forwardingTargetForSelector: .

Например,

@interface MyFakeDictionary: NSObject
{
    NSMutableDictionary *theRealDictionary;
}

/* reimplement whatever init methods you want to use */

- (id)valueForKey:(id)key;

@end

...

@implementation MyFakeDictionary

- (id)valueForKey:(id)key
{
   id val = [theRealDictionary objectForKey:key];
   /* etc, as you like */
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    return theRealDictionary;
}

@end

Так что между MyFakeDictionary и NSMutableDictionary нет отношения наследования, но если вы отправите селектор в MyFakeDictionary, онне понимает (как и любое другое обычное словарное сообщение, кроме того, которое вы заменили), встроенная логика NSObject перенаправит их члену theRealDictionary.Это «имеет», а не «является», с прозрачной пересылкой сообщений, и поэтому удобно устраняет любые проблемы с кластерами классов.

0 голосов
/ 21 апреля 2011

Возьмите код и оберните его следующим образом:

@implementation NSMutableDictionary(myValueForKey)

<your code here>

@end

Это категория в NSMutableDictionary. Категории упрощают добавление или расширение стандартных методов без необходимости создавать подклассы.

Одной из рекомендаций будет использование другого имени метода, поскольку вы не захотите вызывать [super valueForKey:...] - вам нужно будет позвонить [self valueForKey:...]. Таким образом, использование другого имени метода для вашего метода будет отличать вас от стандартного метода.

0 голосов
/ 21 апреля 2011

Обратите внимание при создании подкласса NSMutableDictionary:

из документов Apple:

Methods to Override

In a subclass, you must override both
of its primitive methods:

setObject:forKey: 
removeObjectForKey:
You must also override the primitive methods of the NSDictionary class.
...