»
January 10, 2009
»

Easy way to find if Objective-C class overrides class method

Here is the easy way to find out if Objective-C (Leopard and iPhone SDKs) class implements or overrides some class method (for instance methods use class_getInstanceMethod). I needed to send the message to class only if the class has or does override the method but not to call the method two times for the superclass (to avoid unnecessary if statement and `prepared` ivar).

This could be done also using class_copyMethodList what doesn’t search in superclass but it seemed to involve more work.

#import <objc/objc-runtime.h>

typedef enum LRMethodImplementationType {
  LRMethodNotFound = 0, // method not found
  LRMethodImplement,    // first in tree to implement method
  LRMethodOverride,     // class overrides method
  LRMethodSuper         // class does not override superclass method
} LRMethodImplementationType;

LRMethodImplementationType LRGetClassMethodImplementationType(
  Class class, SEL selector) {
    
  Method method = class_getClassMethod(class, selector);
  if(method) {
    Class superclass = class_getSuperclass(class);
    if(superclass) {
      Method superclassMethod = class_getClassMethod(superclass, selector);
      if(superclassMethod) {
        return method == superclassMethod ? LRMethodSuper : LRMethodOverride;
      } else {
        return LRMethodImplement;
      }
    }
  }
  return LRMethodNotFound;
}

For given classes:

@implementation LRModel     // extends NSObject
- (void)populate {}
@end

@implementation AMUser      // extends LRModel
- (void)populate {}
@end

@implementation AMModerator // extends AMUser
@end

The result is following:

// NSObject    - LRMethodNotFound
// LRModel     - LRMethodImplement
// AMUser      - LRMethodOverride
// AMModerator - LRMethodSuper

Full source code (including debug help function) can be found in pastie.org/309831.

This is reblog from my older blog @ tumblr.

 
Internet Explorer 6
Are you serious?