Swift中的类型分为两种 :
- 值类型
每个值类型的实例都拥有各自唯一的数据,通常它们是结构体,枚举或元组
Array、String和Dictionary都是值类型
- 引用类型
引用类型的实例共享它们的数据,通常是一个类。
class 是引用类型
区别?
值类型最基本的特征就是复制在赋值、初始化和传递参数过程中的数据,并为这个数据创建一个独立
的实例
下面举2个粟子:🙄
// 值类型例子
struct MJJ { var data: Int = 1 }
var a = MJJ()
var b = a // 把a赋值给b
a.data = 42 // a被改变了, b却没有
println("\(a.data), \(b.data)") // prints "42, 1"
// 引用类型的例子
class JJCoder { var data: Int = -1 }
var x = JJCoder()
var y = x // x被复制给了y
x.data = 4 // x指向的数据被修改了 (同时y也被修改了)
println("\(x.data), \(y.data)") // prints "4, 4"
其实是隐式地创建了一个共享的实例。在赋值后,两个实例指向了同一块数据,所以当修改其中一个实例数据的时候,另一个实例的数据也被修改了
安全性方面考虑😀
选择值类型而不是引用类型的一个主要原因是能让你的代码变得更加简单。你在任何情况下用一个值类型,都能够假设你的其他代码不会使它改变,这通常在多线程环境中很有用,如果一个线程中使用的数据被另一个线程给意外的修改了,这通常会产生非常严重的Bug,且相当难以调试。
由于只有当你需要修改数据时两者的区别才会得到体现,所以当你的实例不会对数据进行修改的时候,值类型和引用类型看起来是完全相同的。
你也许会想,写一个完全不可变的类,这或许是有价值的,使用Cocoa的NSObject能简化这个过程,并且能很好地保持原有的语义。现在,你能通过使用不可变的存储属性,以及避免暴露修改数据的接口,从而在Swift里实现一个不可变的类。事实上,大多数的Cocoa类,比如NSURL等,都被设计为不可变的类,然而,Swift当前并没有提供任何语言机制去强制申明一个类不可改变(比如子类化就能修改一个类的实现),只有结构体和枚举才是强制不可变的。
如何抉择:😝
使用值类型:
1. 通过使用==去比较实例的数据
2. 想得到一个实例的独立副本
3. 数据在多线程环境下被修改
使用引用类型(比如使用一个类):
1. 通过使用===去判断两个实例是否恒等
2. 你想要创建一个共享的,可变的对象
网友评论