结构体和类的主要相同点:
1.定义属性
2.定义方法
3.下标语法 访问下标语法
4.定义初始化器
5.extension扩展
6.遵循协议来提供某种功能
主要不同点:
1.类可以被继承
2.类有引用计数,可以控制其释放,类对象是引用类型,可以使用UnsafePointer访问其指针,其内存存储在堆上。
结构体是值类型,存储在栈上。
类对象成员变量在内部函数里修改,结构体不可以,如果一定需要修改可以使用inout或者mutating辅助修改
3.结构体会自动生成成员初始化器,类成员初始化器需要自己生成或者给成员变量初始化值
内存区域分布
内存区域从下到上大致分布是这样的
__text指令->常量区(字符串、常量)->全局区->Heap(swift类)->Stack(栈区)
首先要明白一点 代码打包后实际存放在Mach-O文件中,Mach-O文件是分段的,每个段又分很多的Section,用来存放不同的代码类型。Section大致有这些
TEXT.text : 机器码
TEXT.cstring : 硬编码的字符串
TEXT.const: 初始化过的常量
DATA.data: 初始化过的可变的(静态/全局)数据
DATA.const: 没有初始化过的常量
DATA.bss: 没有初始化的(静态/全局)变量DATA.common: 没有初始化过的符号声明
类的初始化器
结构体会提供默认的初始化器,包含成员变量
类的初始化器需要确定成员变量是有初始化值的。
使用convenience 可以生成指定的初始化器,并且在内部需要调用原初始化器。
可失败初始化器可以进行条件判断,返回可选类型。
类的生命周期
OC、Swift底层都是通过LLVM进行编译的,Swift有自身的swift编译器生成IR代码,OC通过Clang编译器生成IR代码,然后交由LLVM处理生出.o文件(机器码)
swift编译器的部分命令
//分析输出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
Swift对象的内存分配
Swift对象的内存结构实际是个结构体HeapObject (OC是objc_object) ,其中有两个属性Metadata(类的结构)、RefCount(引用计数) ,默认占用16字节大小。
通过源码分析可以得出类的成员变量大致如下
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
}