Swift 属性(下)

222 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情


  1. Swift Optional
  2. Swift Enum
  3. iOS开发 做一个三角形
  4. Swfit 指针类型
  5. Swift 属性(下)
  6. Swift 属性
  7. Swift 小结
  8. Swift 类与结构体(下)
  9. Swift 类的生命周期
  10. Swift 类的初始化器
  11. Swift 类与结构体
  12. OpenGL 压缩纹理
  13. OpenGL 隧道坐标计算
  14. 0penGL 像素格式及数据类型
  15. OpenGL 纹理对象
  16. OpenGL 纹理
  17. OpenGL 模型变化
  18. OpenGL 视图
  19. OpenGL 矩阵
  20. OpenGL 向量
  21. OpenGL 颜色混合
  22. OpenGL 深度测试的潜在风险
  23. OpenGL 浅析深度测试
  24. OpenGL 浅析隐藏面消除
  25. OpenGL 图元连接方式
  26. 记WKWebView与HTML完成交互两三事
  27. OpenGL 渲染流程图解析
  28. OpenGL 控制你的正方形
  29. OpenGL 专业名词解释
  30. OpenGL 环境搭建 - MacOS

接着上一篇,今天我们继续来探索Swift属性的相关内容:

延迟存储属性

  • 延迟存储属性的初始值在其第一次使用时才进行计算。
  • 用关键字 lazy 来标识一个延迟存储属性

类型属性

  • 类型属性其实就是一个全局变量
  • 类型属性只会被初始化一次

属性在Mahco文件的位置信息

在第一节课的过程中我们讲到了 Metadata 的元数据结构,我们回顾一下

struct Metadata{ 
    var kind: Int
    var superClass: Any.Type
    var cacheData: (Int, Int)
    var data: Int
    var classFlags: Int32
    var instanceAddressPoint: UInt32
    var instanceSize: UInt32
    var instanceAlignmentMask: UInt16
    var reserved: UInt16
    var classSize: UInt32
    var classAddressPoint: UInt32
    var typeDescriptor: UnsafeMutableRawPointer 
    var iVarDestroyer: UnsafeRawPointer
}

上一节课讲到方法调度的过程中我们认识了信息,接下来我们需要认识一下,这里面记录了 V-Table 的相关typeDescriptor中的typeDescriptor fieldDescripto

struct TargetClassDescriptor{ 
    var flags: UInt32
    var parent: UInt32
    var name: Int32
    var accessFunctionPointer: Int32
    var fieldDescriptor: Int32
    var superClassType: Int32
    var metadataNegativeSizeInWords: UInt32 
    var metadataPositiveSizeInWords: UInt32 
    var numImmediateMembers: UInt32
    var numFields: UInt32
    var fieldOffsetVectorOffset: UInt32 var Offset: UInt32
    var size: UInt32
    //V-Table
}

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

struct FieldDescriptor {
    MangledTypeName int32
    Superclass int32 
    Kind uint16
    FieldRecordSize uint16
    NumFields uint32
    FieldRecords [FieldRecord]   
}

其中 NumFields 代表当前有多少个属性, FieldRecords 记录了每个属性的信息,FieldRecords 的结构体如下:

struct FieldRecord{
    Flags uint32 
    MangledTypeName int32 
    FieldName int32
}

为什么说指针不安全

  • 比如我们在创建一个对象的时候,是需要在堆分配内存空间的。但是这个内存空间的声明周期是有限的,也就意味着如果我们使用指针指向这块内容空间,如果当前内存空间的生命周期啊到了(引用计数为0),那么我们当前的指针是不是就变成了未定义的行为了。
  • 我们创建的内存空间是有边界的,比如我们创建一个大小为10的数组,这个时候我们通过指针访问到了 index = 11的位置,这个时候是不是就越界了,访问了一个未知的内存空问。
  • 指针类型与内存的值类型不一致,也是不安全的。

下一节,我们详细看看指针类型。