Nope, it's not a bug. It's defined (albeit obscure) behavior of the runtime system.
Just as every instance has an isa
instance variable that points to it's class, every class structure in memory has an isa
member that points to its metaclass. And just as any given class contains metadata about its instances -- including the list of methods that instances respond to -- the class's metaclass contains metadata about the class itself, including the list of methods that the class responds to.
In addition, every class structure has a superclass
member that points to its superclass, which is mirrored in the metaclass hierarchy (i.e., each metaclass's superclass
is another metaclass).
There's one major difference though: the superclass of NSObject
is nil
, while the superclass of the NSObject
metaclass is NSObject
. In other words, NSObject
's metaclass inherits NSObject
's instance methods. As a consequence, Objective-C classes not only respond to their defined class methods, they also respond to NSObject
instance methods.
Confused yet? Greg Parker wrote an excellent blog that includes a very helpful diagram illustrating how this is all wired together:
Hamster Emporium archive - Classes and metaclasses
Edit
Alas, the internets. If the browser you're currently using doesn't display inline PDF documents, here's a link directly to the diagram: