实例对象、类对象、元类之前的关系

isa指向关系

我们通过打印一个对象的类地址,发现一个真理:类对象只有一个!

    LGPerson *p = [[LGPerson alloc] init];
    p.name      = @"Cooci";
    p.age       = 18;
    
    Class class1= [LGPerson class];
    Class class2= p.class;
    Class class3= object_getClass(p);
    NSLog(@"\n%p-\n%p-\n%p",class1,class2,class3);
image.png

其实实例对象、类对象、元类、根元类、NSObject之前有这样一种关系:

  • 实例对象是由类对象初始化来的
  • 类对象由元类初始化而来
  • 元类是一种虚拟的类,由系统帮我创建,不用手动创建
  • 元类由根元类初始化而来
  • 根元类由NSObject初始化而来

其实这里面就是isa的指针指向关系,上面的关系我们可以通过LLDB调试打印结果得来。
需要注意的是,isa是优化过的,说白了就是我们要寻找到isa,当我们读取内存对象的isa地址 & ISA_MASK 过后就是我们的isa执行的对象地址了。


image.png

通过调试,可以证实我们的结论是正确的。
上面只验证了对象,类,和元类的isa指向结果。另外,这里提供一个方法,可以打印一个对象的元类,根元类的地址,进行进一步验证。

- (void)lgPrintClassRelationshipWithObject:(id)objc{
    NSLog(@"*********************************************");

    NSLog(@"\n实例对象地址 - %p",objc);
    NSLog(@"\n类对象地址 - %p",[objc class]);
    NSLog(@"\n父类对象地址 - %p",[objc superclass]);
    NSLog(@"\n元类对象地址 - %p",object_getClass(objc));
    NSLog(@"\n元类的父类对象地址 - %p",[object_getClass(objc) superclass]);
    NSLog(@"\n根元类对象地址 - %p",object_getClass(object_getClass(objc)));
    NSLog(@"\n根元类的父类对象地址 - %p",[object_getClass(object_getClass(objc)) superclass]);
    NSLog(@"\n根根元类对象地址 - %p",object_getClass(object_getClass(object_getClass(objc))));
    NSLog(@"\n根根元类的父类对象地址 - %p",[object_getClass(object_getClass(object_getClass(objc))) superclass]);
    NSLog(@"*********************************************");
}

记住这张图,ISA的指向流程,一切都ok了。


image.png

继承关系

实例对象-->父类-->...-->NSObject-->nil
元类-->父类-->...-->根元类-->NSObject-->nil
下面这张图的继承关系是从上面经典isa和superClass中分离出来的。


image.png

你可能感兴趣的:(实例对象、类对象、元类之前的关系)