结构体
在swift标准库中,绝大多数公开的类型都是结构体, 枚举和类只占很小的一部分。
如Bool、 Int、 Double、 String、Array、Dictionary 等都是结构体。
struct Date {
var year: Int
var month: Int
var day: Int
}
let date = Date(year: 2019, month:11, day: 10)
所有结构体都会默认生成一个初始化器。
结构体的初始化器
编译器根据情况,可能会为结构体生成多个初始化器,宗旨:保证所有的成员都有初始值。 注意: 可选项有默认值nil.
自定义初始化器
一旦在结构体内自定义了初始化器,编译器将不会为它自动生成其他初始化器了。
初始化器的本质
struct Point {
var x: Int = 10
var y: Int = 20
}
struct Point {
var x: Int
var y: Int
init() {
x = 10
y = 20
}
}
这两段代码时等价的, 其调用的汇编是一致的。
类
类与结构体类似, 但是编译器并没有为类自动生成可传入成员值的初始化器。
类的初始化器
- 如果类的所有成员都在初始化时指定了初始值,编译器会为类生成无参的初始化器。
- 成员的初始化都是在初始化器内完成的。
结构体与类的本质区别
结构体是值类型(枚举也是值类型),类是引用类型(指针类型)。
值类型
值类型赋值给var、let 或者给函数传参,是直接将所有内容拷贝一份。类似于文件的复制,属于深拷贝。Dictionary 和 Array 属于值类型,所以也会进行深度拷贝(与OC有所不同)。
在swift 标准库中,为了提升性能,对String, Dictionary, Array, Set 采取了Copy on Write 技术。
- 比如,只有当写的时候,才会进行拷贝的操作。
- 对于标准库的类型赋值操作,Swift保证了其最佳性能,所以没必要为了提升性能而避免赋值。
- 注意点: 不需要修改的值尽量定义为
let。
引用类型
引用类型赋值给var、let 或者函数传参, 是将内存地址拷贝一份。 相当于制作一个文件替身, 属于浅拷贝。
对象堆空间申请过程
在Mac、 iOS中的malloc函数分配的内存大小总是16的倍数。