Swift Struct和Class的异同点

97 阅读2分钟

在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()

结构体内存结构 截屏2023-12-05 10.08.02.png   类的定义和结构体类似,但编译器并没有为类自动生成可以传入成员值的初始化器,如果类的成员变量都有默认值,则系统会为类生成无参数的初始化器; 成员的初始化是在初始化器中完成的

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 常量内部的成员变量可以被修改 截屏2023-12-04 14.36.59.png 类对象的堆空间申请过程

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
}

截屏2023-12-05 09.59.32.png 如果错误,请指正