1、基本概念
结构体和类的主要相同点有:
- 定义存储值的属性
- 定义方法
- 定义下标以使用下标语法提供对其值的访问
- 定义初始化器
- 使用 extension 来拓展功能
- 遵循协议来提供某种功能
主要的不同点有:
- 类有继承的特性,而结构体没有
- 类型转换使您能够在运行时检查和解释类实例的类型
- 类有析构函数用来释放其分配的资源
- 引用计数允许对一个类实例有多个引用
- 栈的内存分配速度快于类
最主要的区别:
类是引用类型。也就意味着一个类类型的变量并不直接存储具体的实例对象,是对当前存储具体实例内存地址的引用。
2、内存区域探究
2.1、内存区域介绍
栈区(stack): 局部变量和函数运行过程中的上下文
Heap: 存储所有对象
Global: 存储全局变量;常量;代码区
Segment & Section:
Mach-O
文件有多个段( Segment
),每个段有不同的功能。然后每 个段又分为很多小的 Section
TEXT.text : 机器码
TEXT.cstring : 硬编码的字符串
TEXT.const: 初始化过的常量
DATA.data: 初始化过的可变的(静态/全局)数据 DATA.const: 没有初始化过的常量
DATA.bss: 没有初始化的(静态/全局)变量
2.2、结构体和class的内存分布
struct LGTeacher{
var age: Int = 18
var name: String = "LG"
var p = LGTutor()
}
class LGTutor {
var age: Int = 10
var name: String = "XL"
}
var t = LGTeacher()
通过命令 frame variable -L t
查看
其中t为值类型,分布在栈区,p为引用类型分布在堆区
3、类的生命周期
3.1、Swift编译
在iOS开发的语言中不管是OC还是Swift后端都是通过LLVM进行编译的
1、OC 通过 clang 编译器,编译成 IR,然后再生成可执行文件 .o(这里也就是我们的机器 码)
2、Swift 则是通过 Swift 编译器编译成 IR,然后在生成可执行文件。
输出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
3.2、Swift生命周期
1、Swift 对象内存分配过程:
__allocating_init
->swift_allocObject
->_swift_allocObject_
->swift_slowAlloc
->Malloc
2、Swift 对象的内存结构 HeapObject (OC objc_object) ,有两个属性: 一个是 Metadata ,一个是 RefCount ,默认占用 16 字节大小。
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
}