Nuzhdin Vladimir
Nuzhdin Vladimir

Reputation: 1832

Can I detect: "Does class overload method of base class"?

I have two methods in my class

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

And I have implementation for both of them. So! Solution like: "Just add NSAssert(NO, @"You mast override this method")" will not help =(

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

Because I have some code over there. And need to write [super configureWithDictionary:dictionary withOptions:options]; in overloaded method. Everyone can use this methods. And I need both! But.

If some developer will overload -[MYClass configureWithDictionary:] it can "work incorrect". Just because this method doesn't call any time. So I need to write something in console. Like: "Please overload method: -[MYClass configureWithDictionary:withOptions:]". And I want to handle it only once in this method:

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

    }
}

But I can't find any solution(in documentation/google/stackoverflow). And can't handle: "Does developer overload method of base class".

May be there are some better solution. But I think it should be the best. If you have some another ideas. Please write bellow =)

I've found only method: +[NSObject instancesRespondToSelector] and of course I know about -[NSObject respondsToSelector:] but as you know it always return YES. I need almost same, but for current class ignoring base.

PS. Any way thanks for your attention. Link to documetation or some article will be very helpful.

Upvotes: 2

Views: 130

Answers (2)

Nuzhdin Vladimir
Nuzhdin Vladimir

Reputation: 1832

I've found solution myself and I think it can help community. So 3 Simple steps.

Step 1: Create category form NSObject with method

+ (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];
}

Step 2: Check does you class overload some method:

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

Step 3: Check all what you need in + (void)initialize. It called once for class(so it will not a lot of CPU time). And it needed only for developers. So Add #ifdef DEBUG directive

+ (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
    }
}

Victory!

Upvotes: 0

Cy-4AH
Cy-4AH

Reputation: 4615

May be it's not exactly what you are asking, but when I need to be sure that child classes overload some required method I do such thing:

@protocol SomeClassRequiredOverload

- (void) someMethodThatShouldBeOverloaded;

@end

@interface _SomeClass
@end

typedef _SomeClass<SomeClassRequiredOverload> SomeClass;

Upvotes: 2

Related Questions