[概念辨析] 结构体与类 值类型与引用类型
NSArray、NSString 等OC中实现的都是类类型
Array、String 等Swift汇总实现的都是引用类型
根据手册上讲的来说
值类型在 传值 的通过拷贝出不同的实例来传值 改变一个实例的属性等并不会在其它实例上体现
而 引用类型在 传值 的时候通过引用 相当于至拷贝了指针一样 不同变量所指向同一个 实例 改变里面的属性等变会影响到所有
结构体定义相关联的数据组的时候使用
否则使用类
类和结构体的选择
在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。
然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。当你在考虑一个工程项目的数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体。
按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:
- 结构体的主要目的是用来封装少量相关简单数据值。
- 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
- 任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
- 结构体不需要去继承另一个已存在类型的属性或者行为。
举例来说,以下情境中适合使用结构体:
- 几何形状的大小,封装一个
width
属性和height
属性,两者均为Double
类型。- 一定范围内的路径,封装一个
start
属性和length
属性,两者均为Int
类型。- 三维坐标系内一点,封装
x
,y
和z
属性,三者均为Double
类型。在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。
字符串(String)、数组(Array)、和字典(Dictionary)类型的赋值与复制行为
Swift 中
字符串(String)
,数组(Array)
和字典(Dictionary)
类型均以结构体的形式实现。这意味着String,Array,Dictionary类型数据被赋值给新的常量或变量,或者被传入函数或方法中时,它们的值会发生拷贝行为(值传递方式)。Objective-C中
字符串(NSString)
,数组(NSArray)
和字典(NSDictionary)
类型均以类的形式实现,这与Swfit中以值传递方式是不同的。NSString,NSArray,NSDictionary在发生赋值或者传入函数(或方法)时,不会发生值拷贝,而是传递已存在实例的引用。注意: 以上是对于字符串、数组、字典和其它值的
拷贝
的描述。 在你的代码中,拷贝好像是确实是在有拷贝行为的地方产生过。然而,在 Swift 的后台中,只有确有必要,实际(actual)
拷贝才会被执行。Swift 管理所有的值拷贝以确保性能最优化的性能,所以你也没有必要去避免赋值以保证最优性能。(实际赋值由系统管理优化)