美文网首页
Swift5.1学习随笔之类class

Swift5.1学习随笔之类class

作者: SAW_ | 来源:发表于2020-04-14 17:11 被阅读0次

    类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中,创建类的实例对象,要像堆空间申请内存,大概流程如下:

    • Clsss.__allocating_init()
    • libsyswiftCore.dylib:_swift_allocObject_
    • libsyswiftCore.dylib:swift_slowAlloc
    • libsystem_malloc.dylib:malloc

    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
    

    相关文章

      网友评论

          本文标题:Swift5.1学习随笔之类class

          本文链接:https://www.haomeiwen.com/subject/rhxtvhtx.html