• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

swift-类属性

武飞扬头像
i_erlich
帮助1

了解属性之前,需要先了解前面的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读取

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbiheg
系列文章
更多 icon
同类精品
更多 icon
继续加载