值类型和引用类型
首先,需要了解Swift中的值类型和引用类型。
在Swift中
值类型: 基本数据类型(Int,Double,String,Array,Dictionary)
引用类型: class, block, function
- 值类型(Value Types):每份实例都保留了一份独有的数据拷贝,一般以结构体(struct)、枚举(enum)或者元组(tuple)的形事出现。
- 引用类型(Referance Types):每个实例共享同一份数据来源,一般以类(class)的形式出现。
Copy on Write(写时复制)
- Copy-on-Write是一种用来优化占用内存大的值类型的拷贝操作的机制。
- 对于Int、String等基本类型的值类型,它们在赋值的时候就会发生拷贝,它们没有Copy-on-Write这一特性(因为Copy-on-Write带来的开销往往比直接复制的开销要大)。
- 对于Array、Dictionary、Set类型,当它们赋值的时候不会发生拷贝,只有在修改的之后才会发生拷贝,即Copy-on-Write。
- 在swift中,当你有一个占用内存很大的一个值类型,并且不得不将它赋值给另一个变量或者当做函数的参数传递的时候,拷贝它的值是一个非常消耗内存的操作,因为你不得不拷贝它所有的东西放置在另一块内存中。
- 为了优化这个问题,Swift对于一些特定的值类型(集合类型:Array、Dictionary、Set)做了一些优化,在对于Array进行拷贝的时候,当传递的值进行改变的时候才会发生真正的拷贝。而对于String、Int等值类型,在赋值的时候就会发生拷贝。
存储方式
- 值类型和引用类型在内存上存储的地方不一样。值类型的值是存储在内存的栈当中。引用类型的值是存储在内存的堆中。
- 在传递值类型和传递引用类型的时候,传递方式不一样。值类型我们称之为值传递,引用类型我们称之为引用传递。
- 引用类型的对象存储在堆中,并且会分配一个内存地址。该内存地址会存储到栈空间,栈空间名为变量名。
即读取引用类型对象的顺序:变量—>内存地址—>实例对象。
1 | //打印内存地址 |
1 | class Person { |
其中,如果引用类型里面包含值类型,值类型会存在引用类型的存储区中。