美文网首页
对象,类,元类之间的关系

对象,类,元类之间的关系

作者: Kates | 来源:发表于2021-06-17 17:06 被阅读0次

在之前的文章对象内存探索中,我们已经知道对象默认都有一个isa指针,这个指针指向的正式对象的类,而在oc中一切皆为对象,那类是否也有isa指针,他的指针指向的是谁呢?
带着这个疑问我们来看看
首先我们来看一个示例:

@interface HFPerson : NSObject
@end
HFPerson *p = [HFPerson alloc];
NSLog(@"%@---%p", p, p);

通过lldb我们来打印p的isa指针指向的类
(lldb) x/4gx p
0x28189a520: 0x000001a102e2d675 0x0000000000000000
0x28189a530: 0x0000000000000000 0x0000000000000000
0x000001a102e2d675 p的isa指针
(lldb) po 0x000001a102e2d675 & 0x0000000ffffffff8ULL
HFPerson
(lldb) p/x 0x000001a102e2d675 & 0x0000000ffffffff8ULL
(unsigned long long) $11 = 0x0000000102e2d670

这边就可以清楚看到isa指针指向的是HFPerson,也就是说对象的isa指向的是类
接下来我们看看类的isa指针
(lldb) x/4gx 0x0000000102e2d670
0x102e2d670: 0x0000000102e2d648 0x00000001f65e60d8
0x102e2d680: 0x00070002838e4a00 0x0005803900000000
(lldb) po 0x0000000102e2d648 & 0x0000000ffffffff8ULL
HFPerson
(lldb) p/x 0x0000000102e2d648 & 0x0000000ffffffff8ULL
(unsigned long long) $13 = 0x0000000102e2d648
咦也是HFPerson,但是我们看到$13 跟 前面的$11不一样,也就是说有两个HFPerson类?

接下来在继续往下看看会不会有第三个HFPerson类
(lldb) x/4gx 0x0000000102e2d648
0x102e2d648: 0x00000001f65e60b0 0x00000001f65e60b0
0x102e2d658: 0x00070002838e4c00 0x0003e03500000000
(lldb)  po 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
NSObject

(lldb) p/x 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
(unsigned long long) $15 = 0x00000001f65e60b0
通过第二个HFPerson类我们继续探索发现他的isa指针指向的是NSObject,而我们看到$15的地址跟原来一样,也就是说到顶了。

这边的NSObject是NSObejct类吗?
(lldb) p/x [NSObject class]
(Class) $17 = 0x00000001f65e60d8 NSObject

咦,发现$17 跟$15地址并不一样,所以上面的NSObject并不是我们所熟知的NSObject类,我们跟他取了一个名字叫\color{#f00}{根元类}
而上面的$13 跟 前面的$11不一样,我们将$13的HFPerson称之\color{#f00}{元类 }
通过上面的示例我们是不是可以得出这样的结论
对象isa->类isa->元类isa->NSObject(根元类)
等等刚刚HFPerson 继承 NSObject,如果有其他类继承HFPerson,那会有影响吗,我们再来实际考察一下

@interface HFStudent : HFPerson
@end
@interface HFPerson : NSObject
@end
HFPerson *p = [HFPerson alloc];
HFStudent *s = [HFStudent alloc];
NSLog(@"%@---%p", p, p); 断点到这里

(lldb) x/4gx s
0x281366340: 0x000001a10488562d 0x0000000000000000
0x281366350: 0x0000000000000000 0x0000000000000000
(lldb) po 0x000001a10488562d & 0x0000000ffffffff8ULL
HFStudent  (对象isa指针指向类,这个没错)

(lldb) p/x 0x000001a10488562d & 0x0000000ffffffff8ULL
(unsigned long long) $2 = 0x0000000104885628
(lldb) x/4gx 0x0000000104885628
0x104885628: 0x0000000104885600 0x0000000104885678
0x104885638: 0x00000001ae8bdb10 0x0000803900000000
(lldb) po 0x0000000104885600 & 0x0000000ffffffff8ULL
HFStudent (类的isa指针指向元类HFStudent)

(lldb) p/x 0x0000000104885600 & 0x0000000ffffffff8ULL
(unsigned long long) $4 = 0x0000000104885600
(lldb) x/4gx 0x0000000104885600
0x104885600: 0x00000001f65e60b0 0x0000000104885650
0x104885610: 0x00030002808703c0 0x0003e03500000000
(lldb) po 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
NSObject (元类的isa指针指向的是根元类)

(lldb) p/x 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
(unsigned long long) $6 = 0x00000001f65e60b0

这样就应该足够证明上面那个结论了
用一张图表示


D998832A-DF53-482C-BA04-AAE1E91260E8.png

元类

我们知道类有继承关系,元类是否也有呢?
同样我们还是用一个例子来说明


Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
object_getClass 获取的是对象的isa指向

    Class tMetaClass = object_getClass(HFStudent.class);
    NSLog(@"%@ meta - %p",tMetaClass,tMetaClass);
    Class tsuperClass = class_getSuperclass(tMetaClass);
    Class pMetaClass = object_getClass(HFPerson.class);
    NSLog(@"%@ meta - %p",pMetaClass,pMetaClass);
    NSLog(@"%@ - %p",tsuperClass,tsuperClass);
    Class psuperClass = class_getSuperclass(tsuperClass);
    Class nMetaClass = object_getClass(NSObject.class);
    NSLog(@"%@ meta- %p",nMetaClass,nMetaClass);
    NSLog(@"%@ - %p",psuperClass,psuperClass);
    Class rsuperClass = class_getSuperclass(psuperClass);
    NSLog(@"%@ - %p",rsuperClass,rsuperClass);
    Class prsuperClass = class_getSuperclass(rsuperClass);
    NSLog(@"%@ - %p",prsuperClass,prsuperClass);

2021-06-19 16:23:20.349082+0800 StoreKitDemo[86485:3135162] HFStudent meta - 0x1053e7698
2021-06-19 16:23:20.349244+0800 StoreKitDemo[86485:3135162] HFPerson meta - 0x1053e76e8
2021-06-19 16:23:20.349344+0800 StoreKitDemo[86485:3135162] HFPerson - 0x1053e76e8
2021-06-19 16:23:20.349440+0800 StoreKitDemo[86485:3135162] NSObject meta- 0x7fff89c111d8
2021-06-19 16:23:20.349540+0800 StoreKitDemo[86485:3135162] NSObject - 0x7fff89c111d8
2021-06-19 16:23:20.349626+0800 StoreKitDemo[86485:3135162] NSObject - 0x7fff89c11200
2021-06-19 16:23:20.349721+0800 StoreKitDemo[86485:3135162] (null) - 0x0

  1. 首先获取了HFStudent的元类tMetaClass,通过class_getSuperclass获取到tMetaClass的父类为tsuperClass(HFPerson元类),然后继续通过class_getSuperclass获取tsuperClass的父类psuperClass(NSObject 根元类),在继续通过class_getSuperclass获取psuperClass的父类为rsuperClass(也是NSObject,但是从地址上看并不是根元类,是NSObject 根类),继续class_getSuperclass获取rsuperClass的父类结果为nil
    从结果可以看出元类也是有继承关系,从而得出下图结论


    39778AC7-7A4B-4D19-9582-99D613D400CF.png

结合上面两个结论我们可以得出苹果之前给的一张isa和继承关系图


EFDA4984-323B-41F0-B102-6B7212ED9652.png

相关文章

  • 对象,类,元类之间的关系

    在之前的文章对象内存探索中,我们已经知道对象默认都有一个isa指针,这个指针指向的正式对象的类,而在oc中一切皆为...

  • Runtime-类与对象

    类与对象的关系 这张图想必大家不会陌生,它展示了对象、类、元类之间的关系 对象(Instance)的isa指针指向...

  • OC对象内存布局

    Q: 属性、变量、变量的值、类方法、对象方法怎么布局?元类、类对象、实例对象、根类之间的关系? A: 属性(包括父...

  • 实例对象-类对象-元类之间的关系

    一.实例: 二、由实例的结果,我们总结出实例对象-类对象-元类之间的关系:

  • iOS类的结构分析

    一、实例对象、类、元类关系分析 1. 实例对象、类、元类关系图解析 我相信上面这张经典的实例对象、类、元类关系图大...

  • 深入理解Objective-C中实例、类对象、元类对象之间的关系

    实例、类对象、元类对象之间的关系可以用下面这张经典的图来展示: 总结: 实例的isa指向类对象 类对象的isa指向...

  • 类结构分析

    这片文章主要分析的是类的结构以及对象-类-元类-根元类之间的走位. 一. isa的指向以及类之间的关系 准备工作定...

  • 07·iOS 面试题·class A 继承 class B,cl

    前言 对于类图,涉及到继承关系,isa 指向关系;对于这个题目,我们需要熟悉对象、类、元类之间的关系,才能准确的画...

  • 005-类结构探索(一)

    前言 前面我们分析了对象&类&元类的层次结构,以及他们之间的关系。显然,类模版cls是我们整个OC面向对象设计里面...

  • UML类图

    UML类图 基本描述: 用于描述类(对象)本身的组成 和 类(对象)之间的各种静态关系。 类之间的关系:依赖、继承...

网友评论

      本文标题:对象,类,元类之间的关系

      本文链接:https://www.haomeiwen.com/subject/mbecyltx.html