【iOS】class-dump源码学习(三)

本文深入探讨了class-dump源码中CDObjectiveC2Processor的`protocolAtAddress:`和`loadClassAtAddress:`方法,详细解析了如何处理协议和类的加载过程,包括协议的实例方法、类方法、实例变量、属性等信息的读取和存储。同时介绍了CDProtocolUniquer的作用和CDObjectiveC2Processor的加载逻辑。
摘要由CSDN通过智能技术生成

上一篇:【iOS】class-dump源码学习(二)

续上一篇讲完CDObjectiveCProcessor的process方法中加载符号表的两个方法,今天继续process方法学习


回到CDObjectiveCProcessor的process方法继续,紧接着加载符号表的是

[self loadProtocols];
[self.protocolUniquer createUniquedProtocols];

顾名思义loadProtocols方法是加载协议表,这里先以CDObjectiveC2Processor的处理做说明

- (void)loadProtocols;
{
    CDSection *section = [[self.machOFile segmentWithName:@"__DATA"] sectionWithName:@"__objc_protolist"];
    
    CDMachOFileDataCursor *cursor = [[CDMachOFileDataCursor alloc] initWithSection:section];
    while ([cursor isAtEnd] == NO)
        [self protocolAtAddress:[cursor readPtr]];
}

很好理解,读取__Data段的__objc_protolist区,然后遍历区获得指针address

看一下CDObjectiveC2Processor的protocolAtAddress:方法对获得的指针address如何处理

首先指针address会被当作键,class-dump定义的CDOCProtocol对象作为值存储在一个CDProtocolUniquer管理类的字典中。

然后根据指针address的地址声明一个CDMachOFileDataCursor的对象cursor,开始读取协议具体字段

struct cd_objc2_protocol objc2Protocol;
objc2Protocol.isa                     = [cursor readPtr];
objc2Protocol.name                    = [cursor readPtr];
objc2Protocol.protocols               = [cursor readPtr];
objc2Protocol.instanceMethods         = [cursor readPtr];
objc2Protocol.classMethods            = [cursor readPtr];
objc2Protocol.optionalInstanceMethods = [cursor readPtr];
objc2Protocol.optionalClassMethods    = [cursor readPtr];
objc2Protocol.instanceProperties      = [cursor readPtr];
objc2Protocol.size                    = [cursor readInt32];
objc2Protocol.flags                   = [cursor readInt32];
objc2Protocol.extendedMethodTypes     = 0;

系统使用cd_objc2_protocol结构来记录协议在mach-o文件中的信息。

如果size字段的大小大于8个指针+两个Int32,意味着extendedMethodTypes字段还有内容

cursor再读取一个指针,说明extendedMethodTypes是一个指针指向了一个新的区域,用于说明extendedMethodTypes

接着开始把cd_objc2_protocol中的字段映射到CDOCProtocol对象中。

  • protocols字段指向了一个储存多个协议地址(应该是父类协议)的地址,储存形式是一个表示count的字段加上count个指向新协议的指针,这些协议指针被放在CDOCProtocol的_protocols字段。
  • instanceMethods字段指向了一个方法列表,由一个cd_objc2_list_header结构加上cd_objc2_list_header.count个cd_objc2_method结构组成。如果前面extendedMethodTypes指针不为空,cd_objc2_method的types会被extendedMethodTypes指向的字符串覆盖。最后cd_objc2_method构成了class-dump的CDOCMethod类对象并作为数组保存在CDOCProtocol的_instanceMethods字段。
//cd_objc2.h
struct cd_objc2_list_header {
    uint32_t entsize;
    uint32_t count;
};

struct cd_objc2_method {
    uint64_t name;
    uint64_t types;
    uint64_t imp;
};
  • classMethods、optionalInstanceMethods、optionalClassMethods字段和instanceMethods处理相同,最后CDOCMethod类对象并作为数组保存在CDOCProtocol的_classMethods等字段。
  • instanceProperties字段指向了一个属性列表,由一个cd_objc2_list_header结构加上cd_objc2_list_header.count个cd_objc2_property结构组成。最后cd_objc2_property构成了class-dump的CDOCProperty类对象并作为数组保存在CDOCProtocol的_properties字段。
struct cd_objc2_property {
    uint64_t name;
    uint64_t attributes;
};

至此CDObjectiveC2Processor的protocolAt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值