Утверждение класса объекта в Objective C - PullRequest
5 голосов
/ 22 ноября 2011

Я часто утверждаю, что объект "isKindOfClass" какого-то класса в Objective-C.Я делаю это так:

NSAssert([obj isKindOfClass:[AClass class]], @"%@ should be kind of class %@", obj, [[AClass class] description]);

Я задаюсь вопросом о лучшем способе сделать ярлык для него.Я думаю об определении макроса, что-то вроде:

#define NSClassAssert(obj, class)  NSAssert([obj isKindOfClass:class], @"%@ should be of class %@", obj, [class description])

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

Ответы [ 2 ]

3 голосов
/ 23 ноября 2011

Нужно спросить точно, почему вы хотите сделать это в первую очередь.Вы сказали:

Учитывая толерантность и динамичность цели c, мне нравится делать код «доказательством злоупотребления».Вместо того, чтобы иметь нераспознанное селекторное сообщение, у меня есть сообщение, сообщающее, к какому классу должен относиться объект.

Если вы передаете объект методу, который не соответствует типу, объявленному в подписито есть вы делаете что-то вроде этого:

- (void)doSomething:(NSArray *)array { /* Do something * }

- (void)doSomethingElse
{
    NSString *string = @"my string";
    [self doSomething:string];
}

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

Конечно, это не защитит вас при использовании более общего типа, такого как id, но если вы беспокоитесь о нераспознанных селекторах, вам действительно следует проверить, реагирует ли объект на этот селектор, вместо этогоиспользования assert:

- (id)doSomething:(id)obj
{
    if ([obj respondsToSelector:@selector(calculateSomething)]) {
        return [obj calculateSomething];
    } else {
        NSLog(@"%@ does not respond to calculateSomething", obj);
    }
}

Или используйте протоколы для проверки доступности методов.


Тем не менее, да, ваш макрос будет работать для вашей намеченной цели.

0 голосов
/ 28 января 2014

Вместо сообщения о нераспознанном селекторе у меня есть сообщение мне, к какому классу должен был быть объект.

Проверка того, принадлежит ли объект определенному классу, очень помогает в обеспечении того, чтобы фрагмент кода вызывался с объектами правильного типа; например, с массивом NSWhatEvers. Objective-C не предоставляет этого из коробки, и ваш код выглядит хорошо; Я использую такой макрос в моем коде, который

#define NSIsKindOf(obj, klass)  NSAssert([obj isKindOfClass:class], @"%@ should be of class %s but is a %@", obj, #klass, [obj class])

Если вы хотите пойти по пути печатания утки - то есть отправить селектор на объект неизвестного происхождения - тогда respondsToSelector:, как указывает @mipadi, - это путь.

...