swift中类型主要分两类,分别是值类型和引用类型。这两种类型的功能类似于OC中的深拷贝和浅拷贝。
类型定义 | 定义类型 | |
---|---|---|
值类型 | 每个实例保留其数据的唯一副本 | struct、enum和tuple |
引用类型 | 实例共享数据的单个副本 | class |
值类型
值类型通常被定义为 struct、enum和tuple。他的主要特点是,每个实例都保留其数据的唯一副本,通俗点说修改 A 实例中的值不会影响到 B 实例。如下所示
1 | struct S { |
引用类型
引用类型通常被定义为 class。他主要的特点是,实例共享数据的单个副本,通俗点说修改 A 实例中的值会影响到 B 实例。如下所示:
1 | class C { |
为什么会存在这两种类型
swift 为什么会同时存在引用类型和值类型,引用类型是不是能满足一切,那为什么还有值类型呢?
想想如果在多线程环境中使用引用类型,此时我们始终获得一个唯一的实例,但是不同的线程可能会同时对实例进行,这时可能会产生难以预料的错误,而这种错误很难进行调试分析。如果是值类型,我们可以通过分析不同的实例,来帮我们轻松的查找和推理代码中出现的问题。
还有一种情况是当实例中没有数据可进行更改时,值类型和引用类型的行为是完全相同的。如果某个类完全不可变,可能会更有价值,swift 中要实现这样的类可以通过结合不可变的属性和避免公开状态的API来实现。而它目前没有提供任何语言机制来实现对结构和枚举的不可变性。OC 中许多累被设计成不可变例如 NSURL。
两种类型如何选择?
在 OC 中,许多 API 都是 NSObject 的子类,当我们在swift中新建一个类型时,如何去选择?
选择值类型
- 实例数据间进行 == 比较有意义
- 副本具有独立的状态
- 数据将在多个线程中使用
选择引用类型
- 实例之间进行 === 比较有意义
- 实例内数据的变化需要共享
以上内容参考以下文章