类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()
,但是类Point
中x、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
中,创建类的实例对象,要像堆空间申请内存,大概流程如下:
Clsss.__allocating_init()
-
libsyswiftCore.dylib:
_swift_allocObject_
-
libsyswiftCore.dylib:
swift_slowAlloc
-
libsystem_malloc.dylib:
malloc
2、在Mac、iOS中的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
网友评论