Swift进阶杂谈2:值类型

本文主要介绍值类型程序员

内存分区模型

为了更好的理解值类型,首先了解内存分区模型,在iOS中,内存主要分为 栈区 堆区 全局区 常量区 代码区五大区域。以下图所示markdown

如图所示spa

  • 栈区的地址比堆区的地址大。
  • 栈是从高地址->低地址,向下延伸,由系统自动管理,是一片连续的内存地址。
  • 堆是从低地址->高地址,向上延伸,由程序员管理,堆空间结构相似于链表,是不连续的。
  • 平常开发中的溢出是指堆栈溢出,能够理解为栈区与堆区边界碰撞的状况。
  • 全局区、常量区都存储在__TEXT cString段。

值类型

值类型的特色

  • 一、地址中存储的是
  • 二、值类型的传递过程当中,至关于传递了一个副本,也就是所谓的深拷贝
  • 三、值传递过程当中,并不共享状态

举个例子

func test() {
    var age = 18
    var age2 = age
    age = 30
    age2 = 45
    
    print("age=\(age),age2=\(age2)")
}

test()
复制代码

断点查看age的栈区地址与内存状况code

  • 获取age的栈区地址:po withUnsafePointer(to: &age){print($0)}
  • 查看age内存状况:x/8g 0x00007ffeefbff410

一样查看age2的栈区地址与内存状况 orm

能够看出,age2的赋值至关于将age中的值拿出来,赋值给了age2。其中ageage2的地址 相差了8字节,从这里能够说明栈空间是连续的、且是从高到低的。内存

结构体是值类型

定义一个结构体,并进行分析开发

struct PDTeacher {
    var age : Int = 16
    var age2: Int = 20
    
}

var t = PDTeacher()
print("end")
复制代码
  • 打印t:po t,可知,打印出来t就是值,没有任何与地址有关的信息

  • 获取t的内存地址,并查看其内存状况

此时将t赋值给t1,若是修改了t1,t会发生改变吗?

  • 直接打印t及t1,能够发现t并无由于t1的改变而改变,主要是由于t1t之间是值传递,即t1和t是不一样的内存空间,是直接将t中的值拷贝t1中。修改t1中的值,是修改的t1的内存空间,是不会影响t的内存空间的。

SIL验证

一样的,咱们也能够经过分析SIL来验证结构体是值类型it

  • SIL文件中,咱们查看结构体的初始化方法,能够发现只有init,而没有malloc,在其中看不到任何关于堆区的分配。

总结

  • 结构体是值类型,且结构体的地址就是第一个成员的内存地址。
  • 值类型在内存中直接存储值
  • 值类型的赋值,是一个值传递的过程,即至关于拷贝了一个副本,存入不一样的内存空间,两个空间彼此间并不共享状态
  • 值传递其实就是深拷贝
相关文章
相关标签/搜索