2008 12 15Class pairs and super
objc_super
's receiver
must be self
, not the metaclass. The metaclass is only used in the second param, as a start point in the super method search.
More Objective-C runtime stuff !
Creating new ObjC classes at runtime is straightforward :
- call
objc_allocateClassPair
to start creation - call
class_addIvar
to add any instance variables - call
objc_registerClassPair
to finish up class creation
You can then add methods with class_addMethod
. Methods can be added anytime, instance variables can only be added before objc_registerClassPair
.
Creating a new ObjC class creates a class pair — a metaclass to hold class methods, a class to hold instance methods. They're really two distinct objects that you can manipulate as such : calling superclass
on a metaclass will retrieve a metaclass.
// Plus sign registers a class method (stored in the metaclass) + (void)alloc; // Minus sign registers an instance method (stored in the class) - (id)init;
objc_getClass("NSView")
retrieves the class, objc_getMetaClass("NSView")
retrieves the metaclass. To add class or instance methods, call class_addMethod
with the metaclass or the class.
As super is not runtime, we need to get the metaclass while handling the super call of a runtime-added method — even though we're in a class method, the runtime sets self
as the class and not the metaclass. The first param of objc_super
is self
, the second is the metaclass to use as a start point for method search.
+ (id)allocWithZone:(NSZone*)zone { ... our custom code ... // Retrieve the meta class id metaclass = objc_getMetaClass(class_getName(self)); // Super call struct objc_super superData = { self, [metaclass superclass] }; return objc_msgSendSuper(&superData, @selector(allocWithZone:), zone); }Objective-C 2.0 Runtime Reference
You can also use object_getClass(self) to return either the class or metaclass depending on wether self is an instance of a class or metaclass respectively.