Dynamic Method Injection (in Objective-C)

When asked what I like the most from the Objective-C programming language, I often refer to its dynamic underpinnings.

Although Objective-C is a superset of C, the way its designers decided to implement the Object model was dynamic. This provides a strong contrast with C++, which, although a superset of C as well, is a static-typed language.

In this post I will show how you can use the Objective-C runtime to dynamically add a method to an (Objective-C) class at runtime.

Let’s start by creating a Dummy class that has no methods whatsoever. I will put everything in the same file for the sake of simplicity, but in real-life code, you’d want to have separate files for the interface and the implementation.

#import <Foundation/Foundation.h>

@interface Dummy : NSObject
@end

@implementation Dummy
@end

Now, let’s implement a method to be dynamically added to Dummy. Interestingly enough, methods to add need to be implemented as C functions.

Here’s our implementation:

void newMethod(id self, SEL _cmd)
{
  printf("Hello from a dynamically added method! (self=%p)\n", self);
}

Now, let’s go to the main function and see how we can inject “newMethod” into the Dummy class. We will need to import the Objective-C runtime.

#import <objc/runtime.h>

int main(int argc, char* argv[])
{
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  
  // Add method to Dummy class (args explained below)
  class_addMethod([Dummy class], @selector(printHello), (IMP)newMethod, "v@:");
  
  Dummy* instance = [[Dummy alloc] init];
  [instance printHello];
  [instance release];
  
  [pool release];
  return 0;
}

When running this program, an output similar to this will be produced:

Hello from a dynamically added method! (self=0x10ad143a0)

So, let’s see how the method was added.

The heavylifting here is done by the class_addMethod function. This function, coming from the Objective-C runtime, allows you to register a new method in a class.

This feat requires a pointer to the function that implements the method (“newMethod”), but lets you assign any name you want to it (I chose “printHello”). Notice that’s the message I send to the Dummy instance.

The strangest parameter is perhaps the last “v@:”. This is actually a code for the argument types received by the “newMethod” function. All valid type codes can be found in the Apple reference, but to make things easier, “v@:” means that the function returns void (v) and receives an Object and a selector.

3 thoughts on “Dynamic Method Injection (in Objective-C)

Comments are closed.