Swift里的值类型与引用类型
本页包含内容:
- 值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 、
枚举(enum)
或者元组(tuple)
的形式出现。 - 引用类型(Reference Type):每个实例共享同一份数据来源,一般以
类(class)
的形式出现。
在这篇博文里面,我们会介绍两种类型各自的优点,以及应该怎么选择使用。
值类型与引用类型的区别
值类型和引用类型最基本的分别在复制之后的结果。当一个值类型被复制的时候,相当于创造了一个完全独立的实例,这个实例保有属于自己的独有数据,数据不会受到其他实例的数据变化影响:
另一方面,复制一个引用类型的时候,实际上是默默地创造了一个共享的实例分身,两者是共用一套数据。因此修改其中任何一个实例的数据,也会影响到另外那个。
// 下面是一个引用类型的例子
var x = C()
var y = x // y是x的拷贝
x.data = 42 // 更改x的数据,等于同时修改了y
Mutation(修改)在安全中扮演的角色
值类型较引用类型来说,会让你更容易在大量代码中理清状况。如果你总是得到一个独立的拷贝出来的实例,你就可以放心它不会被你app里面的其他部分代码默默地修改。这在多线程的环境里面是尤为重要的,因为另外一个线程可能会在暗地里修改你的数据。因此可能会造成严重的程序错误,这在调试过程中非常难以排除。
由于差别主要在于修改数据的后果,那么当实例的数据只读,不存在需要更改的情况下,用哪种类型都是没有分别的。
如何选择类型?
所以当我们想要建立一个新的类型的时候,怎么决定用值类型还是引用类型呢?当你使用Cocoa框架的时候,很多API都要通过NSObject的子类使用,所以这时候必须要用到引用类型class。在其他情况下,有下面几个准则:
什么时候该用值类型:
- 要用==运算符来比较实例的数据时
- 你希望那个实例的拷贝能保持独立的状态时
- 数据会被多个线程使用时
什么时候该用引用类型(class):
- 要用==运算符来比较实例身份的时候
- 你希望有创建一个共享的、可变对象的时候
本章节不是老码的原创,老码认真的阅读了苹果的官方博客,且自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌,还是看不懂请到老码官方微博咆哮。