在Swift标准库中,绝大多数的公开类型都是结构体,而枚举和类只占很小一部分,比如:Bool,Int,Double,String,Array,Dictionary 等常见类型都是结构体 例:
struct MyDate {
var year:Int // 存储属性 8字节
var month: Int// 存储属性 8字节
var day:Int// 存储属性 8字节
}
对象创建 var date = MyDate(year: 2023, month: 12, day: 1)
系统会为结构体自动生成的初始化器(初始化方法),宗旨:保证所有成员都有初始值
struct Point {
var x:Int = 3
var y:Int = 4
}
创建对象 var p = Point()
结构体内存结构
类的定义和结构体类似,但编译器并没有为类自动生成可以传入成员值的初始化器,如果类的成员变量都有默认值,则系统会为类生成无参数的初始化器; 成员的初始化是在初始化器中完成的
class Point {
var x:Int
var y:Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
成员变量有默认值
struct Point {
var x:Int? = 0// 可选项默认值为nil
var y:Int = 0
}
区别 1.结构体是值类型,类是引用类型 2.值类型赋值给var,let 或者给函数传参 是直接将所有内容拷贝一份(类似对文件的拷贝,深拷贝 deepcopy),为了提升性能,String,Array,Dictionary ,Set 采取了Copy On Write(仅当有“写”操作时,才会真正执行拷贝操作)
var s1 = "Jack"
var s2 = s1
s2.append("name")
print(s1)
print(s2)
也就是只有对s2 进行写相关的操作时 才会进行深拷贝
3.引用类型赋值给var,let 或者函数传参,是将内存地址拷贝一份(类似文件替身 快捷方式,浅拷贝)
值类型和引用类型的 let 常量对比,值类型let常量 p和其内部的成员变量不可修改, 引用类型let常量s ,s指针不可重新执行新常量,但是s 常量内部的成员变量可以被修改
类对象的堆空间申请过程
1.Class.__allocating_init()
2.libswiftCore.dylib:_swift_allocObject_
3.libswiftCore.dylib:swift_slowAlloc
4.libsystem_malloc.dylib:malloc(malloc 函数分配的内存大小总是16的倍数)
通过class_getInsstanceSize 可以得知类的对象真正使用的内存大小 类对象的内存结构如下:
class Size{
var width:Int = 1
var height:Int = 2
}
如果错误,请指正