Swift 类的生命周期

307 阅读4分钟

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


  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 类的生命周期的内容:

类的生命周期

要分析类的生命周期,我们先整理下 iOS开发的后端编译:

  • iOS开发的语言不管是OC还是Swift后端都是通过LLVM进行编译的。
  • OC语言 通过 clang 编译器,编译成 IR,然后再生成可执行文件 .o(这里也就是我们的机器码)
  • Swift语言 则是通过 Swift 编译器编译成 IR,然后在生成可执行文件。

分析输出AST

分析输出 AST 的 命令行 内容如下:

分析输出AST

swiftc main.swift -dump-parse

分析并且检查类型输出AST

swiftc main.swift -dump-ast

生成中间体语言(SIL),未优化

swiftc main.swift -emit-silgen

生成中间体语言(SIL),优化后的

swiftc main.swift -emit-sil

生成LLVM中间体语言 (.ll文件)

swiftc main.swift -emit-ir

生成LLVM中间体语言 (.bc文件)

swiftc main.swift -emit-bc

生成汇编

swiftc main.swift -emit-assembly

编译生成可执行.out文件

swiftc -o main.o main.swift

main: 入口函数,

%0: 寄存器,虚拟的,真的寄存器 xcrun swift-demangle

Swift 对象内存分配过程:

  _swift_allocObject_ -----> swift_slowAlloc 
  • Swift 对象的内存结构 HeapObject (OC objc_object) ,有两个属性: 一个是 Metadata ,一个是 RefCount ,默认占用 16 字节大小。
__allocating_init
swift_allocObject
objc_object{
    isa
}

源码中 kind 种类

image.png

类的结构:objc_class\

经过源码分析我们不难得出 swift 类的数据结构

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
}

扩展

汇编 常见指令

  • mov: 将某一寄存器的值复制到另一寄存器(只能用于寄存器与寄存器或者寄存器 与常量之间传值,不能用于内存地址),如:
mov x1, x0 将奇存器 X0 的值复制到寄存器 x1 中
  • add:将某一奇存器的值和另一奇存器的值 相加 并将结果保存在另一寄存器中, 如:
add x0, x1, x2 将寄存器 x1 和×的值相加后保存到寄存器 X中
  • sub 将某一寄存器的值和另一奇存器的值 相减 并将结果保存在另一寄存器中:
sub x0, x1, x2 将寄存器 x1 和x2的值相減后保存到寄存器 X0中
  • and:将某一奇存器的值和另一寄存器的值 按位与 并将结果保存到另一奇存器中, 如:
and x0, x0, #0x1 将寄存器 x?的值和常量 1按位与后保存到寄存器 x中
  • orr:将某一奇存器的值和另一寄存器的值 按位或 并将结果保存到另一奇存器中, 如:
orr x0, x0, #0x1 将寄存器 x。 的值和常量 1按位或后保存到寄存器 x中
  • str:将寄存器中的值写入到内存中,如:
str x0, [x0,×8] 将寄存器 x0中的值保存到栈内存 [x0 + x8]
  • ldr:将内存中的值读取到寄存器中,如:
ldr x0, [x1, x2〕将奇存器 x1 和奇存器 x2 的值相加作为地址,取该内存地址的值放寄存器 x中
  • cbz:和。比较.如果结果为零就转移(只能跳到后面的指令)
  • cbnz:和非。 比较.如果结果非零就转移(只能跳到后面的指令)
  • cmp: 比较指令
  • b: (branch)跳转到某地址(无返回)
  • bl:跳转到某地址(有返回)
  • ret:子程序(两数调用)返回指令,返回地址已默认保存在奇存器 0×30 中