Classes and Meta-Classes and Methods in Objective-C
A small post on how instance and class methods are implemented in objective-c, and how to add methods at runtime.
Classes and Meta-Classes
Recently I commented about classes and meta-classes in Objective-C. All objects have a type (their class). All objects have a reference to that class as a
Class object (see definitions below). Instance methods for a given type are effectively stored in that
Class object. Class-level methods, however, are not. Class-level methods are stored on the Class object’s reference to its meta-class object (also of type
This is very important when you want to add or swizzle instance-level and class-level methods at runtime, because you must add instance-level methods to the type’s class, and class-level methods by adding them to the meta-class for that class. Below is a simple interface/implementation demonstrating fetching classes and meta-classes (partially taken from Classes and Meta-classes but with additions).
It outputs something like the following:
DKObject's class is 0x100002908 DKObject's class is 0x100002908 DKObject's class is 0x100002908 DKObject's meta-class is 0x100002930 DKObject's meta-class is 0x100002930 DKObject's meta-class is 0x100002930
(Just note that the references are different for the class and meta-class.)
The one tricky point is that the
class method for Class objects does not return the meta-class for that class (as you might think it would), but returns itself. Since the meta-class contains the class-level methods, in order to add a class-level method, we have to get the meta-class for a class. As shown above, you can od:
(Note that a
Class is also an
The above may not be an exhaustive list of ways of doing this.
There are probably many posts explaining this (though I didn’t find many), but you use the
class_addMethod() function to add both instance-level and class-level methods. The function itself does not differentiate which kind of method you are adding – it can’t from the selector. You pass a type’s
Class reference for adding instance-level methods, and a meta-class
Class reference for adding class-level methods.
So, let’s say we want to add the following two methods to NSObject:
The code to do that would be:
Note that for class-level methods, we pass the meta-class
Class, fetched with
object_getClass(). The last two parameters of the method are well documented elsewhere, so I won’t bother to explain them here.