OC底层-类结构体分析

前言

上一篇已经分析了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这个结构体中,如下图:

cache_t图1
cache_t图2

通过上面的图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


图2

图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属性和实例方法,但是得不到我们的成员变量和类方法,之后我会带大家继续探索,喜欢的麻烦点个赞,😊

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。