Search code examples
objective-cobjective-c-runtime

Why does class method of a class object does not return the meta class?


The following code:

  NSObject *a = [[NSObject alloc] init];
  Class c = [a class];
  Class meta1 = [[a class] class];
  Class meta2 = objc_getMetaClass("NSObject");
  NSLog(@"%@ %d", c, class_isMetaClass(c));
  NSLog(@"%@ %d", meta1, class_isMetaClass(meta1));
  NSLog(@"%@ %d", meta2, class_isMetaClass(meta2));

produce:

NSObject 0
NSObject 0
NSObject 1

More than that [c isKindOfClass:c] returns true.


Solution

  • meta1 is the result of calling class on a value of type Class, i.e. the calls invokes a class method (+ class) – similarly the call [c alloc] (after the assignment to c in the code) would be equivalent to [NSObject alloc].

    The default implementation of + class comes from NSObject and is defined to simply return the class it was called on. So in the example code both c and meta1 have as value NSObject's Class.

    That tells you why-by-definition meta1 is not the meta class. If your question is why-by-design does it not return the meta class then that is a different question best asked of one of the language's designers!

    HTH