美文网首页Swift
Swift 结构体 与 类

Swift 结构体 与 类

作者: 奋斗的小马达 | 来源:发表于2021-12-17 17:16 被阅读0次

    结构体

    一、结构体 是值类型

    二、结构体的存储位置

    结构体的存储位置 根据不同情况来分
    1、如果结构体(值类型)在函数中创建 它存储在栈空间
    例如:

    func testStruct(){
        struct Point {
            var x: Int = 0
            var y: Int = 0
        }
        var p = Point()
    }
    
    由于结构体在  testStruct 函数中创建 所以他存储在 栈空间
    

    2、 如果值类型在全局区创建的 它存储在代码区
    例如:

    import Foundation
    
    struct Point {
        var x: Int
        var y: Int
    }
    
    var p = Point.init(x: 10, y: 10)
    
    

    三、说明 + 示例

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

    比如 Bool、 Int 、Double、 String 、Array、 Dictionary

    所有的结构体 都有编译器自动生成的初始化器
    编译器会根据实际情况 可能会为结构体生成多个初始化器
    生成初始化器的宗旨是:保证所有成员都有初始值(这是秘诀 要记住)

    例如下面的几种类型
    1、Point x 和 y 没有初始值

    struct Point {
        var x: Int
        var y: Int
    }
    
    //由于初始化器的宗旨是:保证所有成员都有初始值
    // Point 中 的 x 和 y 都没有初始值 
    // 所以编译器自动给Point 生成一个两个参数的初始化器
    
    var p = Point.init(x: 10, y: 10)
    

    2、Point1 x没有初始值 y有初始值

    struct Point1 {
        var x: Int
        var y: Int = 10
    }
    
    //由于初始化器的宗旨是:保证所有成员都有初始值
    // Point1 中 的 x没有初始值   y有初始值 
    // 所以编译器自动给Point1 生成如下两个初始化器
    
    var p1 = Point1.init(x: 10, y: 30)
    var p11 = Point1.init(x: 30)
    
    

    3、Point2 x和y都有初始值

    struct Point2 {
        var x: Int = 20
        var y: Int = 10
    }
    
    //由于初始化器的宗旨是:保证所有成员都有初始值
    // Point2 中 的 x  和  y 都有初始值 
    // 所以编译器自动给Point2 生成如下四个初始化器
    
    var p21 = Point2.init(x: 0, y: 20)
    var p22 = Point2.init(x:0)
    var p23 = Point2.init(y:0)
    var p24 = Point2.init()
    
    

    4、Point3 x和y都为可选型 (因为可选型初始值 都为nil)

    struct Point3 {
        var x: Int?
        var y: Int?
    }
    
    //由于初始化器的宗旨是:保证所有成员都有初始值
    // Point3 中 的 x  和  y   都为可选型 
    // 由于可选型都有默认值 nil
    // 所以编译器自动给Point3 生成如下四个初始化器
    
    var p31 = Point3.init(x: 0, y: 20)
    var p32 = Point3.init(x:0)
    var p33 = Point3.init(y:0)
    var p34 = Point3.init()
    

    自定义初始化器

    注意⚠️:一旦定义了结构体的初始化器 编译器就不会帮助它生成其他的初始化器

    例如

    struct Point4 {
        var x: Int = 0
        var y: Int = 0
        init(x: Int,y: Int){
            self.x = x
            self.y = y
        }
    }
    
    //由于我们自定义了一个初始化器  所以编译器就不会再为我们生成初始化器
    //所以 我们 初始化Point4 只能用我们自己定义的
    var p4 = Point4.init(x: 10, y: 20)
    

    一、类 是引用类型 (指针类型)

    类的定义和结构体类似 但是编译器不会为类自动生成可传入成员值的初始化器

    注意⚠️:
    如果类的所有成员都在定义的时候指定了类初始值 编译器就会为类生成无参的初始化器
    成员的初始化就是在无参的初始化器中完成的
    例如

    class Point {
        var x: Int = 0
        var y: Int = 1
    }
    
    // 因为 类的所有成员都在定义的时候指定了类初始值
    //所以编译器为Point 自动生成了一个初始化器
    
    let p1 = Point.init()
    

    类 和 结构体 的本质区别

    在swift中 结构体和类 都能定义方法
    结构体是值类型
    枚举也是值类型

    类是引用类型(指针类型)

    举例说明

    struct Point {
        var x: Int = 3
        var y: Int = 4
    }
    
    class Size {
        var width = 1
        var hight = 2
    }
    
    
    func test(){
        var point = Point()
        var size = Size()
    }
    
    

    text 函数在栈空间的分布情况如下图所示 (假设开始地址是 0x10000)


    text 函数在栈空间的分布.png

    解析:
    由于 text 是一个函数 所以他存储在栈空间
    栈空间 前16个字节 分别存放 Point (值类型)的两个成员变量的值

    后8个字节 存放的 是一个指针变量(也就是 size size是一个指针)

    size 指针变量内存中存放的是 size对象内存地址(这个地址是在堆空间 因为size是一个对象 创建的时候需要 alloc 开辟堆空间)

    size对象的前 8个字节 存放的是 类型信息的地址 它指向size的元类 元类来存放类的一些信息(如:方法、类方法)

    8--16个字节 存放的是 对象的引用计数
    后面就是存放类的一些成员信息

    值类型 与 引用类型的区别

    值类型 赋值给 var、let 或者 给函数传参 是直接将内容拷贝一份 会产生全新的文件副本

    修改 原数据 对 副本没有任何影响
    修给 副本 对 原数据没有任何影响

    注意⚠️:
    在Swift标准库中,为了提升性能,String、Array、Dictionary、Set采取了Copy On Write的技术 (也就是说 只有在对其进行修改的时候才会去深度拷贝 如果不修改仅仅是浅拷贝)
    比如仅当有“写”操作时,才会真正执行拷贝操作

    对于标准库值类型的赋值操作,Swift 能确保最佳性能,所有没必要为了保证最佳性能来避免赋值

    建议:不需要修改 尽量换成let

    例如

    var s1 = "Jack" 
    var s2 = s1 
    print(s1)
    s2.append("_Rose")
    print(s2)
    

    当代码走到14行时 s1 和 s2 他们俩指向的是同一块内存 如下图所示

    47E1DF5C72CCA51DE99C1AC111A55194.png

    当代码走到16行时 s1 和 s2 他们俩指向的是不同内存 如下图所示


    A51727869D5DC2B9EACED04D55992885.png

    原因是因为 s2 进行了改写 所以就就调用 copy

    相关文章

      网友评论

        本文标题:Swift 结构体 与 类

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