swift-类属性

了解属性之前,需要先了解前面的swift-类结构内容 - swift-类结构源码探寻

FieldDescriptor

TargetClassDescriptor {
    var Flags: ContextDescriptorFlags  // uint32
    var Parent: TargetRelativeContextPointer // Int32
    var Name: TargetRelativeDirectPointer // Int32
    var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
    var Fields: FieldDescriptor // Int32
    var SuperclassType: TargetRelativeDirectPointer // Int32
    var MetadataNegativeSizeInWords: uint32_t
    var MetadataPositiveSizeInWords: uint32_t
    var NumImmediateMembers: uint32_t
    var NumFields: uint32_t
    var FieldOffsetVectorOffset: uint32_t
    var VTableOffset: uint32_t
    var VTableSize: uint32_t
    // ......... VTable部分
}

其中 Fields 记录了当前的属性信息, 源码结构如下

// Field descriptors contain a collection of field records for a single
// class, struct or enum declaration.
struct FieldDescriptor {
    MangledTypeName int32
    Superclass int32  
    Kind uint16  
    FieldRecordSize uint16 
    NumFields uint32  // 应该就是多少个属性了
}

并未发现有属性,至此,如果是你的话,你会怎么继续探究源码来确定类的属性结构

按部就班,如果源码没有直给的信息,那就从给定的方法去找,总归会有关联的

在这里插入图片描述

继续 搜索, 盲目搜搜了一圈,同时FieldDescriptor全局搜索 getFields(), 根据找到的内容多属于猜测的成分,不得不意识到,已经迷失目标了

其实,回过头来

在这里插入图片描述

熟悉的东西又来了

指针偏移,也就是 FieldDescriptor 结构内存 向下平移自己所占的内存空间,得到 FieldRecord

FieldRecords 记录了每个属性的信息

struct FieldRecord {
    Flags uint32
    MangledTypeName int32
    FieldName int32
}

FieldRecord应该就是目标了,有FieldName属性,一个属性自然一个FieldName,自然会有多个FieldRecords [FieldRecord]

补充 FieldDescriptor

struct FieldDescriptor {
    MangledTypeName int32
    Superclass int32  
    Kind uint16  
    FieldRecordSize uint16 
    NumFields uint32  // 应该就是多少个属性了
    FieldRecords [FieldRecord]
}

至于 最终属性的获取

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

内存迭代器出现了

在这里插入图片描述

再次回看细节

多个FieldRecord 应该是连续的

此时找到内存块的第一个 FieldRecord,

在这里插入图片描述
在这里插入图片描述

Flags 占用4字节内存, 主要是起到标识作用

MangledTypeName 占4字节

FieldName 占4字节

在上面找到的第一个FieldRecord内存基础上,需要继续偏移 两个4字节,第3个4字节为 属性名称,

其实 找到的FieldName 还不是 最终目标

RelativeDirectPointer FieldName, 这里是 name的相对偏移量

所以第3个4字节的位置 + 偏移量,最终得到目标属性

类属性与MachO

  • descriptor

在这里插入图片描述

0x7AC8 + 0xFFFFDF60 = 0x100005A28

0x100005A28 - 虚拟基址0x100000000 = 0x5A28

  • descriptor内存
    在这里插入图片描述

    0x5A38 + 0x2010 = 0x7A48

  • FieldDescriptor内存
    在这里插入图片描述

    0x7A48 + 4个4字节 = 0x7A58

    0x7A58 开始,偏移到第3个4字节即为 FileRecord.FieldName

    0x7A60 + 0xFFFFFFB3 = 0x100007A13

    0x100007A13 - 虚拟基址0x100000000 = 0x7A13

  • FieldName 内存
    在这里插入图片描述

相较于OC底层源码,猜测可能是为了兼容OC的缘故吧,swift源码中模板层级教OC更繁琐了些,正因为如此,才能保障向上兼容,同时又能继续兼容oc消息机制吧

swift-类属性-MachO读取

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值