Swift5.1学习随笔之类class

2020-04-14  本文已影响0人  SAW_

类class

类的定义和结构体类似,但是编译器并没有为类自动生成可以传入成员值的初始化器,需要自己实现初始化initializer

class Point {
    var x: Int = 0
    var y: Int = 0
}
var p1 = Point() 
var p2 = Point(x: 10, y: 20) //报错:Argument passed to call that takes no arguments
var p3 = Point(x: 10) //报错:Argument passed to call that takes no arguments
var p4 = Point(y: 10) //报错:Argument passed to call that takes no arguments

上面代码段可以看出,除了p1,其他三个初始化代码都报错,说明类不会自定生成初始化器
但是由于Point内部成员x、y有默认初始值,编译器依然会自动生成一个无传入参数的初始化器

下面的代码段中Point类成员无初始值的情况下编译器会报错
因为编译器会生成无参数的初始化器Point(),但是类Pointx、y都无默认值的情况下,到时候类的对象创建完毕之后,代码很不完全

class Point { //报错:Class 'Point' has no initializers
    var x: Int
    var y: Int
} 
var p1 = Point() //报错:'Point' cannot be constructed because it has no accessible initializers

类的初始化器

如果类的成员都在定义的时候指定了初始值,编译器会为类生成无参数的初始化器
成员的初始化是在初始化器中完成的

class Point {
    var x: Int = 0
    var y: Int = 0
}
var p = Point()

同结构体struct一样,上面的代码等价于下面的代码:

class Point {
    var x: Int
    var y: Int
    init() {
        x = 0
        y = 0
    }
}
var p = Point()

结构体和类的本质区别

根据上面类的初始化器代码来看,结构体非常的相似,在Swift中,结构体都能定义方法。

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

class Size {
    var width = 1
    var height = 2
}

struct Point {
    var x = 3
    var y = 4
}

func test() {
    var size = Size() 
    var point = Point()
}

上面代码中Point跟Size的内存分布状态如下图:


接下来通过汇编查看类和结构体的初始化流程。
为了证明初始化是不是在堆空间,查看有没有调用alloc malloc等关键词
1、通过汇编查看,结构体Point的初始化汇编代码没有查询到相关的代码,可以说明结构体的初始化是在栈空间。
2、通过汇编查看类Size的初始化过程,依次可以看到__allocating_init() malloc libsystem_malloc.dylib:malloc: malloc_zone_malloc 等实现,可以说明类的初始化是在堆空间。

对象的堆空间申请过程
1、在swift中,创建类的实例对象,要像堆空间申请内存,大概流程如下:

2、在MaciOS中的malloc函数分配内存大小总是16的倍数
3、通过class_getInstanceSize可以得知类的对象真正使用的内存大小

struct Point {
    var x = 11
    var test = true
    var y = 22
}
var point = Point()
class_getInstanceSize(type(of: p)) // 40
class_getInstanceSize(Point.self) // 40
上一篇 下一篇

猜你喜欢

热点阅读