前言
上一篇已经分析了isa的内部结构,这篇文章我们主要来分析下objc_class的内部结构,以及如何验证。
探索
我们主要探索的是基于781的objc源码,新的runtime中部分关于objc_class的代码如下:
我这边会带着大家了解下里面的一些参数,比如isa之前说过了,这里就不说了,superclass指向的当前类的父类,cache和bits也不是本章说明的重点,本章将重点说明的是class_rw_t这个结构体。
1.1 properties探索
我们知道iOS采用了内存偏移,首先要获取到bits这个结构体,然后通过通过调用它的data()方法,从而获取到class_rw_t,那么如何获取到bits呢,我们知道isa占8个字节,superclass占8个字节,那么cache占多少字节呢,我们进入cache_t这个结构体中,如下图:
通过上面的图1和图2,我们可以得到cache占了16个字节,那么要想得到bits那么我们就需要偏移32位,接下来我们在调试好的objc源码中创建两个类分别为LGPerson和LGTeacher,LGPerson.h里面代码如下:
#import "LGTeacher.h"
@interface LGPerson : LGTeacher{
NSString* smile;
}
@property(nonatomic,copy) NSString* hx_name;
-(void)sayNB;
+(void)say666;
@end
LGPerson.m里面代码如下:
#import "LGPerson.h"
@implementation LGPerson
-(void)sayNB{
}
+(void)say666{
}
@end
LGTeacher.h里面代码如下:
#import <Foundation/Foundation.h>
@interface LGTeacher : NSObject
@end
LGTeacher.m里面代码如下:
#import "LGTeacher.h"
@implementation LGTeacher
@end
main.m调用如下,并加上断点:
Xcode中的lldb指令如下:
我们知道0x1000022d0是首地址,那么如何计算出它偏移32位后的地址呢,我们使用科学型计算器将它转换成10进制,然后再加上32,最后再转换成16进制得到0x1000022F0,接下来继续执行lldb指令如下图:
图1中为什么要执行p $4.properties()呢,因为我们发现class_rw_t结构体中有properties方法,如下图所示:
我们发现我们先通过获取$2从而得到bits,然后调用data方法,得到class_rw_t这个结构体指针,然后访问这个结构体指针得到它的内部数据,然后进行访问properties方法得到list数组,从而得到property属性。
1.2 methods探索
其实这个methods的探索和properties探索差不多,我们都需要先获取class_rw_t这个结构体,然后访问methods方法,得到方法的list数组,从而得到具体的方法,lldb指令如下:
总结
我们通过探索中的properties方法和methods方法可以得到我们的property属性和实例方法,但是得不到我们的成员变量和类方法,之后我会带大家继续探索,喜欢的麻烦点个赞,😊