https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID82
跟C++/Java的类、结构体功能类似, Swift也提供了结构体和类的语法。
在Swift语言里,结构体和类的区别:
1、结构体在栈里, 类在堆里; Swift通过ARC即自动引用计数机制释放堆内存, 栈变量超出作用域后被释放;
2、结构体是值传递, 类是引用传递(跟Java一样);
3、赋初值方式不同;
下面是结构体的实现方法:
struct Resolution {
var width = 0
var height = 0
}
//结构体都是在栈中
var res1 = Resolution() //实例化结构体
var res2 = Resolution(width: 10, height: 11) //Xcode会提示模板, 类是不能这样赋初值的!
var res3 = res2 //值传递,将res2的值传给res3后, 二者不再有任何关系!
res2.width = 13 //修改的是结构体res2的width属性, 不会影响res3
print("res2 width:\(res2.width), res3 width:\(res3.width)")
输出:
res2 width:13, res3 width:10
再看类的实现方法:
//类对象实例化在堆中
class ResolutionExt {
var width = 0
var height = 0
lazy var instance = "abc" //只在第一次调用时实例化
}
//左侧引用都在栈里, 右侧实例化类在堆中
var resext1 = ResolutionExt() //不能像结构体那样初始化成员变量
var resext2 = resext1
var resext3 = ResolutionExt() //在堆中创建实例, resext3是引用并存在栈中
resext1.width = 5
print("ext1 width:\(resext1.width), ext2 width:\(resext2.width)")
因为resext2和resext1指向同一个类实例, 所以通过这2个引用读写的是同一块内存。
前面提到了结构体是值传递, 每个结构体实例都是一块独立的内存空间;而类是引用传递, 多个变量或常量可以指向同一个类对象, 那么如何判断2个类引用是否指向同一个对象呢?
Swift提供了===和!==关键字(3个字符), 分别实现判断相等和判断不等, 类似于Java的==和!= 。
if resext2 === resext1 { //Swift判断2个引用指向同一个对象使用3个等号即===
print("ext2 and ext1 point same object")
}
if resext1 !== resext3 { //判断2个引用指向不同的对象
print("ext1 is't ext3")
}
就像上边这样,判断类引用是否相同。
关于Swift的类和结构体, 你只要记住一句话: Swift的类是分配在堆里(ARC自动回收), 结构体分配在栈中(超出作用域被回收)!