typedef struct objc_class *Class;
^ That is a forward declaration for an objc_class
pointer. It gives it the nice friendly name Class
.
Now lets take a look at the objc_class
struct:
(Removing Objective-C 2.0 checks to shorten it up)
struct objc_class {
Class isa;
};
//This is really saying
struct objc_class {
struct objc_class *isa;
};
So now we have a struct that points to its own type. But why you ask?
Taken from Inside the Objective-C Runtime, Part 2
The Class pointed to by the Class' isa (the Class' Class) contains the
Class' class methods in its objc_method_list. Got that? The
terminology used in the runtime is that while an object's isa points
to its Class, a Class's isa points to the object's "meta Class".
So what about a meta Class' isa pointer? Well, that points to the root
class of the hierarchy (NSObject in most cases). (In the Foundation
framework each meta class of a subclass of NSObject "isa" instance of
NSObject.) And yes, by the way, NSObject's meta Class' isa points back
to the same struct -- it's a circular reference so no Class' isa is
ever NULL.
So according to that description when you create a class inheriting from NSObject
you have an isa
that points to its class type which points to its meta class which points to its root class (NSObject
) which contains a circular reference to itself. This explains the reason why it requires two steps to determine if an object is an instance or a class.
Lets say you create the following class:
@interface MyClass : NSObject
@end
@implementation MyClass
@end
If you were able* to traverse the isa pointer you would get the following:
*You can not since the isa
is protected. See Cocoa with Love post below for creating your own implementation.
Class c = myClassInstance->isa; //This would be the MyClass
c = c->isa; //This would be MyClass' meta class
c = c->isa; //This would be NSObjects meta class
c = c->isa; //This going forward would still be the NSObjects meta class
...
Once c == c->isa
you will know you are at the root object. Remember that Objective-C is a proper superset of C, which does not natively have object-oriented constructs such as inheritance. This along with other implementation details, such as pointers to super classes which make up the full class hierarchy, allows Objective-C to provide object-oriented features. For more information on classes and meta-classes see the post on Cocoa with Love: What is a meta-class in Objective-C?