美文网首页2022swift 面试大全
第五节 结构体、类、值类型、引用类型

第五节 结构体、类、值类型、引用类型

作者: 天明天 | 来源:发表于2021-01-31 10:42 被阅读0次

    一. 结构体

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

    • Bool,Int,Double,String,Array,Dictionary等常见类型都是结构体。
    • 自己创建结构体
    struct Date {
       var year:Int //存储属性
       var month:Int
       var day:Int
    }
    var date = Date(year:2020,month:02,day:26)//初始化成员
    
    • 所有的结构体都有一个编译器自动生成的初始化器(initialize 、 初始化方法、构造方法、构造器)
    1. 结构体的初始化器
    • 编译器可能会为结构体生成多个初始化器,宗旨:保证结构体的所有成员变量都有初始值。
      Ex:


      截屏2020-02-26上午10.27.14.png
    • 如果存储属性有初始值,可以不用初始化它。
    • 结构体存在可选项的属性初始化
    struct Student{
       var name: String?
       var age : Int?
    }
    
    var stu = Student(name:"chen",age:16)//初始化方法 
    var stu = Student() //初始方法 两个方法都可以
    var stu = Student("name")
    
    1. 自定义初始化器
    • 如果你自己自定义初始化器后,编译器不会再给你生成。
    struct Point  {
    
       var  x :Int
       var y : Int
    
       init(x: Int,y:Int){
           self.x = x
           self.y = y 
        }
    }
    
    var p1 = Point(x : 10, y : 20)
    
    
    • 初始化器的本质,一下两段代码完全等效:


      截屏2020-02-26上午10.39.01.png
    • 占用内存:
    print(MemoryLayout<Point>.size)//16字节
    print(MemoryLayout<Point>.stride)//16
    print(MemoryLayout<Point>.alignment)//8
    
    

    二.类

    1.类基础
    • 类的定义与结构体是类似的,但是编译器没有为类自动生成可以传入成员变量的初始化器。
    class Point {
       var x: Int = 0 // 这里要给初始化值
       var  y : Int = 0
    }
    
    var p = Point()//无参数的初始化器可以调用成功。
    
    • 如果类的所有成员都有初始化值,编译器会为我们生成无参数的初始化器。


      截屏2020-02-26上午11.08.51.png
    2.结构体与类的本质区别
    • 结构体 是值类型,与枚举类似。类是引用类型(指针类型)


      截屏2020-02-26上午11.16.22.png
    • Size class 存储在 内存的 堆空间(即:汇编有没有调用 alloc,malloc方法开辟空间),Point struct 存储在栈空间

    • 查看 对象的占用内存空间大小:
      导入import Foundation

    func textP&S{
    
     class Size{
          var width = 1
          var height = 2
       }
    
    Struct Point{
         var x = 3
         var y = 4
      }
    }
    
    var ptr = malloc(1)
    print(malloc_size(ptr)) //分配给16字节
    

    *在 Mac 与 IOS 中 系统分配内存的大小 都是16的倍数。

    3.值类型

    • 值类型,赋值给 var ,let 或者给函数传值,是直接将所有 内容 拷贝一份,类似于对文件进行 copy,这个是 深拷贝。
      截屏2020-02-26下午2.59.55.png
      此时, p1.x = 10, p1.y = 20. P1 不受影响。
    • 汇编规律:


      截屏2020-02-26下午3.09.42.png
    • 值类型的 赋值操作:
    • String,Array,Dictionary等都是值类型
    var s1 = "123"
    var s2 = s1
    s2.append("234")
    print(s1)//返回“123”
    print(s2)// 123234
    
    • 当编译器 有写入操作时候,才会进行真的的拷贝动作。
    • 不需要修改的 需要定义成 let

    4. 引用类型 (类)

    • 引用类型给var、let 赋值或者传参时,是将 内存地址 拷贝一份
    • 类似于制作一个文件替身(快捷方式、链接),指向同一个文件,属于浅拷贝。


      截屏2020-02-26下午3.36.41.png
    截屏2020-02-26下午3.46.08.png
    • 引用类型的赋值操作 浅拷贝,指向的内存地址是一样的

    5.值类型、引用类型的 let

    struct Point {
     var x: Int
     var  y: Int
    }
    
    class Size {
    
        var width:Int
        var height:Int
    
       init(width :Int,height:Int){
       
            self.width = width
            self.hieght = height
       }
    }
    
    截屏2020-02-26下午6.03.49.png
    • 注意这里的区别:
      let 结构体: 指针跟成员都不能改变
      let 类: s 本身的指针(内存)不能改变,但是成员能改变。
    • 获取 类本身占用多少内存的方法


      截屏2020-02-26下午6.15.10.png
    • class_getInstanceSize(Point.self) //后面加类型,或者class_getInstancellSize(type(of : p))//这里 p是对象,返回40,表示至少需要分配多少字节。

    6.嵌套类型

    截屏2020-02-26下午6.23.27.png

    三.方法,枚举、结构体、类里面都可以定义方法

    1.在外部的方法函数,在枚举、结构体、类里面 的函数就叫做方法。

    • 内部方法在调用时,需要先实例化对象。
    • 函数、方法都存贮在代码区,不会存在类、结构体里面。

    相关文章

      网友评论

        本文标题:第五节 结构体、类、值类型、引用类型

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