一、类与结构体的对比
1.在 Swift 中类和结构体有很多共同之处:
- 定义属性用来存储值;
- 定义方法用于提供功能;
- 定义下标脚本用来允许使用下标语法访问值;
- 定义初始化器用于初始化状态;
- 可以被扩展来默认所没有的功能;
- 遵循协议来针对特定类型提供标准功能。
2.类比结构体多出的功能:
- 继承允许一个类继承另一个类的特征;
- 类型转换允许你在运行检查和解释一个类实例的类型;
- 反初始化器允许一个类实例释放任何其所被分配的资源;
- 引用计数允许不止一个对类实例的引用。
结构体与类的本质区别为结构体是值类型,类是引用类型(其实也可以理解为指针类型)。
也就是说一个类类型的变量并不直接存储具体的实例对象,而是对当前存储具体实例内存地址的引用。所以它们还有一个最直观的区别就是存储的位置不同:一般情况,值类型存储的在栈上,引用类型存储在堆上。
- 栈区(stack): 局部变量和函数运行过程中的上下文
- Heap: 存储所有对象
- Global: 存储全局变量;常量;代码区
- Segment & Section: Mach-O 文件有多个段( Segment ),每个段有不同的功能。然后每 个段又分为很多小的 Section
- TEXT.text : 机器码
- TEXT.cstring : 硬编码的字符串
- TEXT.const: 初始化过的常量
- DATA.data: 初始化过的可变的(静态/全局)数据 DATA.const: 没有初始化过的常量
- DATA.bss: 没有初始化的(静态/全局)变量
- DATA.common: 没有初始化过的符号声明
可以通过cat
命令获取具体的内存区域
二、Swift编译过程
Swift
的编译过程与OC
有所区别,虽然它们的后端都是使用LLVM
来编译生成.o
可执行文件,但是前端OC
使用Clang
生成IR
,Swift
的编译器内部包含Clang
,扩展了Swiftc
来生成对应的 IR
。并且有一点需要注意Swift
没有预处理过程,所以之前在 OC
中通过宏定义完成的一些常量等,在 Swift
中通通不可用...
1.Parse 语法解析器
分析输出AST语法分析解析器是一个简单的递归解析器(在lib/Parse中实现),带有一个集成的、手工编码的 lexer.cpp。解析器负责生成没有任何语义或类型信息的抽象语法树(abstractsyntax Tree,AST),并针对输入源的语法问题发出警告或错误。
swiftc main.swift -dump-parse
2.语义分析
语义分析(在lib/Sema中实现)负责获取解析后的 AST,并将其转换为格式良好、完全检查类型的 AST 形式,附上了所有类型的信息,针对源代码中的语义问题抛出 warning 或 error。
swiftc main.swift -dump-ast
3.生成中间体语言(SIL),未优化
SIL 又是一种高级的、特定于 Swift 的中间语言,适合进一步分析和优化 Swift 代码。SIL 也是一种 SSA 形式的 IR,lib/SILGen 这个库会将类型检查的 AST 降低为所谓的 raw SIL,这是一种原始的SIL。
swiftc main.swift -emit-silgen
4.生成中间体语言(SIL),优化后的
通过以下命令再进一步进行优化,输出优化之后的 SIL。SIL 的这部分优化(在lib/Analysis、lib/ARC、lib/LoopTransforms和lib/Transforms中实现)对程序执行额外的高级、特定于 Swift 的优化,包括不限于:自动引用计数优化、非虚拟化和通用专门化等
swiftc main.swift -emit-sil
5.生成LLVM中间体语言 (.ll文件)
swiftc main.swift -emit-ir
6.生成LLVM中间体语言 (.bc文件)
swiftc main.swift -emit-bc
7.生成汇编
LLVM 可以继续优化它并生成机器代码
swiftc main.swift -emit-assembly
8.编译生成可执行.out文件
swiftc -o main.o main.swift
swift 内存结构
struct HeapObject{
var metadata: UnsafeRawPointer
var refcounted1: UInt32
var refcounted2: UInt32
}
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
}
Swift
对象的内存结构HeapObject
(类似于OC
的objc_object
) ,有两个属性: 一个是 Metadata
,一个是 RefCount
,默认占用 16 字节大小