• 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部分
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其中 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  // 应该就是多少个属性了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

    在这里插入图片描述

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

    其实,回过头来

    在这里插入图片描述

    熟悉的东西又来了

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

    FieldRecords 记录了每个属性的信息

    struct FieldRecord {
        Flags uint32
        MangledTypeName int32
        FieldName int32
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    补充 FieldDescriptor

    struct FieldDescriptor {
        MangledTypeName int32
        Superclass int32  
        Kind uint16  
        FieldRecordSize uint16 
        NumFields uint32  // 应该就是多少个属性了
        FieldRecords [FieldRecord]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    至于 最终属性的获取

    在这里插入图片描述

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

    内存迭代器出现了

    在这里插入图片描述

    再次回看细节

    多个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读取

  • 相关阅读:
    CocosCreator让一个物体跟随鼠标移动(两种方式 本地坐标系和世界坐标系)
    基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
    第2章-数据处理-2.2-数据整合
    ROS+Gazebo中红绿黄交通灯如何实现?
    k8s修改集群IP--不重置集群
    golang的管道阻塞问题
    element-plus自动引入组件报错,例如collapse、loading
    云原生题目整理(待更新)
    Nacos源码分析专题(五)-Nacos小结
    2023年辽宁省数学建模竞赛A题铁路车站的安全标线
  • 原文地址:https://blog.csdn.net/qq_42431419/article/details/127827855