Is it possible to find where in a class hierarchy the method retrieved by class_getInstanceMethod
is coming from? For example, say Class A implements myMethod. Now say i've subclassed Class A in Class A1. If I call class_getInstanceMethod(ClassA1, myMethod)
, is it possible to tell whether the resulting method has been overridden in ClassA1 or comes directly from A1?
I suppose it would be possible to compare the memory addresses of the IMPs if you had access to both ClassA and ClassA1, but I don't have direct access to A.
You can always access a class' superclass, so you can pass it along to class_getInstanceMethod
or class_getMethodImplementation
with the same SEL
and compare the IMP
addresses to see if the method was overridden by the subclass.
This gets a bit hairier if you want to get at the root class which defines this method.
Anyway, here goes:
static inline BOOL isInstanceMethodOverridden(Class cls, SEL selector, Class *rootImpClass) {
IMP selfMethod = class_getMethodImplementation(cls, selector);
BOOL overridden = NO;
Class superclass = [cls superclass];
while(superclass && [superclass superclass]) {
IMP superMethod = class_getMethodImplementation(superclass, selector);
if(superMethod && superMethod != selfMethod) {
overridden = YES;
if(!rootImpClass) {
//No need to continue walking hierarchy
break;
}
}
if(!superMethod && [cls respondsToSelector:selector])) {
//We're at the root class for this method
if(rootImpClass) *rootImpClass = cls;
break;
}
cls = superclass;
superclass = [cls superclass];
}
return overridden;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With