Могу ли я определить: существует ли метод перегрузки класса базового класса?

У меня в классе два метода

- (void)configureWithDictionary:(NSDictionary*)dictionary;
- (void)configureWithDictionary:(NSDictionary*)dictionary withOptions:(XWTreeItemConvertationToNSDictionaryOption*)options;

И у меня есть реализация для них обоих. Так! Решение вроде: «Просто добавьте NSAssert (NO, @« Вы должны переопределить этот метод »)» не поможет = (

- (void)configureWithDictionary:(NSDictionary*)dictionary withOptions:(XWTreeItemConvertationToNSDictionaryOption*)options;
{
    NSAssert(NO, @"You mast override this method"
}

Потому что у меня там есть код. И нужно написать [super configureWithDictionary:dictionary withOptions:options]; в перегруженном методе. Этим методом может пользоваться каждый. И мне нужно и то, и другое! Но.

Если какой-нибудь разработчик -[MYClass configureWithDictionary:] перегрузит, он может "работать некорректно". Просто потому, что этот метод не вызывается в любое время. Поэтому мне нужно что-то написать в консоли. Типа: «Перегрузите метод: -[MYClass configureWithDictionary:withOptions:]». И я хочу обработать это только один раз в этом методе:

+ (void)initialize
{
    if (self == [self class]) {

    }
}

Но я не могу найти никакого решения (в документации / google / stackoverflow). И не могу справиться: «Не перегружает ли разработчик метод базового класса».

Может быть есть какое-нибудь решение получше. Но я считаю, что он должен быть лучшим. Если у вас есть другие идеи. Напишите пожалуйста ниже =)

Я нашел только метод: +[NSObject instancesRespondToSelector] и, конечно, я знаю о -[NSObject respondsToSelector:], но, как вы знаете, он всегда возвращает ДА. Мне нужно почти то же самое, но для текущего класса, игнорирующего базу.

PS. В любом случае спасибо за внимание. Ссылка на документацию или статью будет очень кстати.


person Nuzhdin Vladimir    schedule 14.10.2015    source источник


Ответы (2)


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

@protocol SomeClassRequiredOverload

- (void) someMethodThatShouldBeOverloaded;

@end

@interface _SomeClass
@end

typedef _SomeClass<SomeClassRequiredOverload> SomeClass;
person Cy-4AH    schedule 14.10.2015
comment
Хороший трюк. Я буду использовать это в своей работе. Спасибо =)! Но это не может не помочь иностранному разработчику найти проблему. Грустный = ( - person Nuzhdin Vladimir; 14.10.2015
comment
Это решение подходит для проверки + инициализации, потому что оно не будет скомпилировано, а не прервется во время выполнения. Ошибка компиляции подскажет пользователю, что делать. - person Ben Scheirman; 14.10.2015

Я сам нашел решение и думаю, что это может помочь сообществу. Итак, 3 простых шага.

Шаг 1. Создайте категорию NSObject с помощью метода

+ (NSArray*)methodNamesForClass_WithoutBaseMethodsClasses
{
    unsigned int methodCount = 0;
    Method *methods = class_copyMethodList(self, &methodCount);
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:methodCount];
    for (unsigned int i = 0; i < methodCount; i++) {
        Method method = methods[i];
        [array addObject:[NSString stringWithFormat:@"%s", sel_getName(method_getName(method))]];
    }
    free(methods);
    return [array copy];
}

Шаг 2: Проверьте, не перегружаете ли вы класс каким-либо методом:

[[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:))]

Шаг 3. Отметьте все, что вам нужно, в + (void)initialize. Он вызывается один раз для класса (так что это не займет много процессорного времени). И это нужно только разработчикам. Итак, добавьте директиву #ifdef DEBUG

+ (void)initialize
{
    if (self == [self class]) {
#ifdef DEBUG
        if ([[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:))] && ![[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:withOptions:))]) {
            NSAssert(NO, @"Please override method: -[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(@selector(configureWithDictionary:withOptions:)));
        }
#endif
    }
}

Победа!

person Nuzhdin Vladimir    schedule 15.10.2015