Quoting from Cocoa with Love
Every object has a class. This is a fundamental object-oriented concept but in Objective-C, it is also a fundamental part of the data. Any data structure which has a pointer to a class in the right location can be treated as an object.
In Objective-C, an object's class is determined by its isa
pointer. The isa
pointer points to the object's Class.
And as a proof of it, here's the declaration of id
as a pointer to the objc_object
struct.
typedef struct objc_object {
Class isa;
} *id;
So here we get to the point. What is a Class
?
Let's look at the definition
Class
is defined as follows (it may actually vary depending on the runtime, but let's keep it simple)
struct objc_class {
Class isa;
}
typedef struct objc_class *Class;
As you can see a Class
has a isa
pointer as well. It looks suspiciously like the objc_object
definition and the reason is simple: Class
is in fact an object.
But what is the class of a Class
? It's - by definition - a meta-class.
According to the same source (in bold the part that tackles your question directly),
The meta-class, like the Class
before it, is also an object. This means that you can invoke methods on it too. Naturally, this means that it must also have a class.
All meta-classes use the base class' meta-class (the meta-class of the top Class
in their inheritance hierarchy) as their class. This means that for all classes that descend from NSObject
(most classes), the meta-class has the NSObject
meta-class as its class.
Following the rule that all meta-classes use the base class' meta-class as their class, any base meta-classes will be its own class (their isa pointer points to themselves). This means that the isa pointer on the NSObject
meta-class points to itself (it is an instance of itself).
For further reading on the subject, here's another great explanation by Greg Parker.