Home » Apple » iPad » iPhone » Mac OS X » Add methods to obejct at runtime in Objective-C

Add methods to obejct at runtime in Objective-C

Please, read this post for more understanding…

Function for add method to object is class_addMethod

Adds a new method to a class with a given name and implementation.

1
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

Parameters
cls
    The class to which to add a method.
name
    A selector that specifies the name of the method being added.
imp
    A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd.
types
    An array of characters that describe the types of the arguments to the method. For possible values, see Objective-C Runtime Programming Guide > Type Encodings. Since the function must take at least two arguments—self and _cmd, the second and third characters must be “@:” (the first character is the return type).
Return Value
    YES if the method was added successfully, otherwise NO (for example, the class already contains a method implementation with that name).

Discussion
class_addMethod will add an override of a superclass’s implementation, but will not replace an existing implementation in this class. To change an existing implementation, use method_setImplementation.

    An Objective-C method is simply a C function that take at least two arguments—self and _cmd. For example, given the following function:

1
2
3
4
void myMethodIMP(id self, SEL _cmd)
{
// implementation ....
}

you can dynamically add it to a class as a method (called resolveThisMethodDynamically) like this:

1
class_addMethod([self class], @selector(resolveThisMethodDynamically), (IMP) myMethodIMP, "v@:");

Declared In
runtime.h

Let’s dig into the Objective-C runtime. There are two structures we need to deal with:

1
2
3
4
5
6
7
8
9
10
11
struct objc_method {
  SEL method_name;
  char *method_types;
  IMP method_imp;
};

struct objc_method_list {
  struct objc_method_list *obsolete;
  int method_count;
  struct objc_method method_list[1];
};

This looks kinda scary, but it’s actually not too bad. The steps are basically:

0. Make a function
1. Create an objc_method instance
2. Register the function name
3. Give the objc_method a pointer to the function
4. Add the objc_method to a objc_method_list
5. Pass the objc_method_list to class_addMethods
6. There is no step 6!

So here’s all the code to do that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#import

// create a class with no methods
@interface EmptyClass : NSObject { }
@end

@implementation EmptyClass
@end

// define the function to add as a method
id sayHello ( id self, SEL _cmd,... )
{
  NSLog (@"Hello");
}

void addMethod ()
{
  // create the method

  struct objc_method myMethod;
  myMethod.method_name = sel_registerName("sayHello");
  myMethod.method_imp  = sayHello;
 
  // build the method list.
  // this memory needs to stick around as long as the
  // methods belong to the class.

  struct objc_method_list * myMethodList;
  myMethodList = malloc (sizeof(struct objc_method_list));
  myMethodList->method_count = 1;
  myMethodList->method_list[0] = myMethod;
 
  // add method to the class
  class_addMethods ( [EmptyClass class], myMethodList );
 
  // try it out
  EmptyClass * instance = [[EmptyClass alloc] init];
  [instance sayHello];
  [instance release];
}

Resources:
Theocacao – all typing by Scott Stevensov
Objective-C Runtime Reference

Comments are closed.