Objective-C Runtime - Self, Super Class, Meta Class

ObjC_class_diagram

//Test.m
@implementation Test

#define ClsLog(tag, cls, isaCls) NSLog(@"%30s %s<%p>, isa:%s<%p>", tag, class_getName(cls), cls, object_getClassName(cls), isaCls)

- (void)test {
    Class cls = [self class];
    Class isaCls = object_getClass(cls);
    ClsLog("[self class]", cls, isaCls);

    cls = [super class];
    isaCls = object_getClass(cls);
    ClsLog("[super class]", cls, isaCls);

    cls = [self superclass];
    isaCls = object_getClass(cls);
    ClsLog("[self superclass]", cls, isaCls);

    cls = [super superclass];
    isaCls = object_getClass(cls);
    ClsLog("[super superclass]", cls, isaCls);

    cls = [Test superclass];
    isaCls = object_getClass(cls);
    ClsLog("[Test superclass]", cls, isaCls);

    cls = [Test class];
    isaCls = object_getClass(cls);
    ClsLog("[Test class]", cls, isaCls);

    cls = objc_getMetaClass("Test");
    isaCls = object_getClass(cls);
    ClsLog("[Test meta]", cls, isaCls);

    cls = objc_getMetaClass(object_getClassName(cls));
    isaCls = object_getClass(cls);
    ClsLog("[Test meta isa]", cls, isaCls);

    cls = [cls superclass];
    isaCls = object_getClass(cls);
    ClsLog("[Test meta isa superclass]", cls, isaCls);
}

@end
            [self class] Test<0x105e001f8>, isa:Test<0x105e00220>
           [super class] Test<0x105e001f8>, isa:Test<0x105e00220>
         [self supercls] NSObject<0x10654dd28>, isa:NSObject<0x10654dd50>
        [super supercls] NSObject<0x10654dd28>, isa:NSObject<0x10654dd50>
         [Test supercls] NSObject<0x10654dd28>, isa:NSObject<0x10654dd50>
            [Test class] Test<0x105e001f8>, isa:Test<0x105e00220>
             [Test meta] Test<0x105e00220>, isa:NSObject<0x10654dd50>
         [Test meta isa] NSObject<0x10654dd50>, isa:NSObject<0x10654dd50>
[Test meta isa supercls] NSObject<0x10654dd28>, isa:NSObject<0x10654dd50>
//runtime/NSObject.mm
@implementation NSObject

+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

+ (Class)superclass {
    return self->superclass;
}

- (Class)superclass {
    return [self class]->superclass;
}

@end

//runtime/objc-class.mm
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

////
const char *object_getClassName(id obj)
{
    return class_getName(obj ? obj->getIsa() : nil);
}

const char *class_getName(Class cls)
{
    if (!cls) return "nil";
    assert(cls->isRealized()  ||  cls->isFuture());
    return cls->demangledName();
}