iOS底层学习第二节:OC类探索
一、(objc)对象与(class)类与(metaClass)元类的关系
上一节我们稍微写了一下OBJC1版本的objc_class,这里首先先祭出三张图,分别是objc_objcet,objc_class,对象与类与元类的关系图
所有的对象(instance)底层都是c/c++结构体,都是继承自objc_objcet,实例对象里面存有isa,成员变量
所有的类对象(class)实现于objc_class,继承于objc_objcet,里面有isa,superClass,cache,bits(原本所有的)
所有的元类(metaClass)对象也是实现于objc_class,继承于objc_objcet,里面有isa,类方法
oc万物皆对象(继承之objc_objcet)
二、通过LLDB探究底层结构
首先定义两个类,FFPerson,FFStudent,FFStudent继承自FFPerson
1.通过xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp 命令将oc代码转化为cpp代码,然后可以发现FFPerson,FFStudent,NSobjcet的关系和存放的属性,
2.然后我们运行程序,打上断点研究objc_class
1)实例对象和类对象和元类对象的关系
2)通过地址获得类对象的属性定义,方法
通过地址偏移的方式(32位地址偏移)获得类对象的bits的指针。通过指针调用方法获得data,在通过class_rw_t 结构体获得定义,方法
1.p/x FFStudent.class 获取class的地址
2.p (class_data_bits_t *)0x0000000100008398
获得class_data_bits_t * ,这个地址为class地址偏移0x20而来
3.p $1->data() 通过指针调用data()方法 获得 class_rw_t *
4.p *$2获得地址内容
5.p $3.properties() 我们查看源码可以发现class_rw_t这里面有存放了methods,properties,protocols,然后调用对应的方法可以获得内存数据
6.p $4.list.per 获得属性定义列表指针
7.p *$6 获得指针内容
8.p $7.get(0) 通过结构体方法调用获得属性定义
然后可以查看下面这张图
3)使用MachOView分析内存
三、类结构面试题
这个面试题主要还是有坑点,我下面的图放一下isKindOfClass和isMemberOfClass源码
主要注意两个点。1.实例对象和类调用这两个方法的不同点,2.元类对象isa是NSObject的元类对象,NSObject元类对象的superClass是NSObject类对象
答案是1000 1111