关于值类型和引用类型的一些小解惑
最近在看Swift文档, 看到String这里的时候看到一个值类型的问题, 以前也一直没有怎么去深究其中的问题, 当看到这个问题的时候还真有点蒙, 后来看了其他一些资料, 也算是弄明白了.
首先得弄明白什么是值类型, 什么是引用类型, 在Swift
中的类型分为两类: 一. 值类型, 每个值类型的实例都拥有各自唯一的数据, 通常是结构体, 枚举或元祖; 二. 引用类型, 引用类型的实例共享它们的数据, 通常是一个类(类的属性).
有什么区别?
值类型最基本的特征就是进行值拷贝. 初始化和传递参数过程中的数据, 并为这个数据创建一个独立的实例. 在Swift
中String
是值类型, 而在OC
中, 要想达到这样的效果, 就要使用copy
来修饰才能达到.
而复制一个引用类型的时候, 其实是隐式地创建了一个共享的实例. 在复制后, 两个实例指向了同一块数据, 所以当修改其中一个实例数据的时候, 另一个实例的数据也被修改了. 在OC
中NSString
, NSArray
, NSDictionry
就是引用类型, 这也就是为什么要在当属性是这些数据类型的时候要用copy修饰了, 就是为了数据的安全性, 防止因为别人的修改而改变重要的数据.
如何选择
在写Cocoa
程序的时候, 大多数APIs都需要从NSObject继承, 这就已经是一个类了(引用类型), 使用值类型在一下情况:
- 通过使用==去比较实例的数据(比较的是值)
- 想得到一个实例的独立副本
- 数据在多线程环境下被修改
使用引用类型:
- 通过使用===去判断两个实例内存地址是否相等
- 想创建一个共享的, 可变的对象
在Swift中 Array、String和Dictionary都是值类型,他们的行为和C语言中的int类似,每个实例都有自己的数据,你不需要额外做任何事情,比如做一个显式的copy,防止其他代码在你不知情的情况下修改等,更重要的是,你能安全地在线程间传递它,而不需要使用同步技术。在提高安全性的精神下,这个模型将帮助你在Swift中写出更多可预知的代码。