Check if subclass overrides a method

前端 未结 7 2271
耶瑟儿~
耶瑟儿~ 2021-02-09 13:15

Is it possible to check whether a subclass implements a method that exists either in its immediate superclass or in some superclass of its superclass, etc?

E.g. I subcla

相关标签:
7条回答
  • 2021-02-09 13:50

    Expanding on ZeMoon's answer, I found that there wasn't enough logic to satisfy all cases. I needed to add a check to ensure that instances of the next superclass in the loop implement the specified selector at all. Subclasses of UIView are one example.

    while (objSuperClass != Nil) {
        isMethodOverridden = ([objSuperClass instancesRespondToSelector:selector]) && 
                             ([object methodForSelector:selector] !=
                              [objSuperClass instanceMethodForSelector:selector]);
    
        if (isMethodOverridden) {
    
        }
    }
    
    0 讨论(0)
  • 2021-02-09 13:54

    Using the runtime, you want to use the function Method

    * class_copyMethodList ( Class cls, unsigned int *outCount );
    

    This will give you a list to work with.

    0 讨论(0)
  • 2021-02-09 13:57

    Unfortunately, there is no equivalent to respondsToSelector: that will do precisely this job for you. As you will probably know, respondsToSelector: works in the way that it will return YES as long as the class itself or any of its superclasses implements this method.

    But why not just put an empty implementation of the method into your custom subclass, that way you make sure that calling it doesn't have any effect and doesn't call the same method in the superclass. Did you think about this?

    Update: While there is no method equivalent to respondsToSelector:, you might want to take a look at the Objective-C Runtime. It's a library that allows you to inspect characteristics of a class during runtime (a bit similar to Java reflections). Check out the reference here.

    0 讨论(0)
  • 2021-02-09 13:57

    Not the optimal solution but you can keep a boolean member to your UIView subclass (let's call it UIViewSub indicating if the desired behavior is implemented by the class and check that boolean before using the method.

    Your subclasses (those inheriting UIViewSub) will set/unset this member accordingly in its construction (i.e if it does override it with implementation or not)

    0 讨论(0)
  • 2021-02-09 13:58

    You might ask Why?!

    0 讨论(0)
  • 2021-02-09 14:11

    Based on this answer by Mert Buran.

    You can create a simple method to check whether a given object overrides a given selector (method):

    -(BOOL)checkIfObject:(id)object overridesSelector:(SEL)selector {
    
        Class objSuperClass = [object superclass];
        BOOL isMethodOverridden = NO;
    
        while (objSuperClass != Nil) {
    
            isMethodOverridden = [object methodForSelector: selector] !=
            [objSuperClass instanceMethodForSelector: selector];
    
            if (isMethodOverridden) {
                break;
            }
    
            objSuperClass = [objSuperClass superclass];
        }
    
        return isMethodOverridden;
    }
    

    This can be called as follows:

    [self checkIfObject:someObject overridesSelector:@selector(someSelector)];
    
    0 讨论(0)
提交回复
热议问题