Swift5.1-结构体和类

194 阅读2分钟

结构体

在swift标准库中,绝大多数公开的类型都是结构体, 枚举和类只占很小的一部分。

BoolIntDoubleStringArrayDictionary 等都是结构体。

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
    }
}

这两段代码时等价的, 其调用的汇编是一致的

类与结构体类似, 但是编译器并没有为类自动生成可传入成员值的初始化器。

类的初始化器

  • 如果类的所有成员都在初始化时指定了初始值,编译器会为类生成无参的初始化器。
  • 成员的初始化都是在初始化器内完成的。

结构体与类的本质区别

结构体是值类型(枚举也是值类型),类是引用类型(指针类型)。

值类型

值类型赋值给varlet 或者给函数传参,是直接将所有内容拷贝一份。类似于文件的复制,属于深拷贝。DictionaryArray 属于值类型,所以也会进行深度拷贝(与OC有所不同)。

在swift 标准库中,为了提升性能,对String, Dictionary, Array, Set 采取了Copy on Write 技术。

  • 比如,只有当写的时候,才会进行拷贝的操作。
  • 对于标准库的类型赋值操作,Swift保证了其最佳性能,所以没必要为了提升性能而避免赋值。
  • 注意点: 不需要修改的值尽量定义为let

引用类型

引用类型赋值给varlet 或者函数传参, 是将内存地址拷贝一份。 相当于制作一个文件替身, 属于浅拷贝。

对象堆空间申请过程

在Mac、 iOS中的malloc函数分配的内存大小总是16的倍数。