属性(Properties)
- 在类型(类,结构,枚举)中定义的值被称为属性。
字段 属性 Java 有 无 C# 有 有 Swift 无 有 - 按存储方式分,属性可分为:存储属性(stored properties 存储在常量或变量中的属性)和计算属性(computed properties 经过计算由get返回由set设置的属性)。
存储属性可以加上懒惰(lazy)标签,表示属性初始化时间延后。
存储属性可以加上属性观测器(property observers),用于监视对属性的访问。willSet观测器在属性设置之前被调用,didSet观测器则在属性设置之后被调用。(可读可写)存储属性 只读存储属性 懒惰存储属性 (可读可写)计算属性 只读计算属性 示例 var v: Int
var v = 10
var v = 10 {
willSet {print(newValue)}
didSet {print(oldValue)}
}let v: Int
let v = 10lazy var v = V() var v: Int {
get {return ...}
set {... = newValue}
}var v: Int{
return ...
}计算并设置
属性值的时间类型初始化时 类型初始化时 属性初次访问时 属性每次访问时 属性每次访问时 - 按所有者分,属性可分为:实例属性(instance properties 附属于类型实例的属性)和类型属性(type properties 附属于类型本身的属性)。
关键字 类 结构 枚举 实例属性 无 无 / 类型属性 static
classstatic static
方法(Methods)
- 在类型(类,结构,枚举)中定义的函数被称为方法。
- 方法有两种:实例方法(instance methods 由类型实例调用的方法)和类型方法(type methods 由类型本身调用的方法)。
关键字 类 结构 枚举 变动性实例方法 无 mutating mutating 非变动性实例方法 无 无 无 类型方法 static
classstatic static
初始化(Initialization)
- 存储属性必须有初值。可以在声明时赋缺省值,也可以在构造器赋初值。
存储属性为可选值时,其缺省值为nil。
赋初值时属性观测器不会被调用。
- 构造器(Initializers)语法形式为 init(外部名1 内部名1: 类型1,外部名2 内部名2: 类型2 ...)
缺省形式为 init(外部名1兼内部名1: 类型1,外部名2兼内部名2: 类型2 ...)
即构造器的所有参数缺省外部名与内部名相同,要省略外部名需要把外部名设置为下划线。
自动引用计数(ARCAutomatic Reference Counting)
- 语言中没有垃圾回收器,采用自动引用计数来管理内存:对于同一个实例,创建时引用计数为0,多一次引用则引用计数自动加1,少一次引用则引用计数自动减1,引用计数为0时该实例自动被释放。
class Person {} let p1 = Person() // 引用计数为1 let p2 = p1 // 引用计数为2 p2 = nil // 引用计数为1 p1 = nil // 引用计数为0,实例被释放
- 引用计数会带来循环引用(cyclic references)问题:A实例内部包含一个指向B实例的引用,而B实例内部也包含一个指向A实例的引用。由于A实例和B实例引用计数都不为0,两者均无法释放。
- 为了解决循环引用问题,语言中引入弱引用(weak references)和非占有引用(unowned references),常规引用被称为强引用(strong references)。
强引用:参与引用计数的常规引用。
弱引用:不参与引用计数,生命周期中可指向空值的观察者引用。
非占有引用:不参与引用计数,生命周期中不应该指向空值的观察者引用。
所谓不参与引用计数,是说对于一个实例,即便多一次或者少一次弱引用或非占有引用,该实例的引用计数也不会发生变化,即弱引用或非占有引用不影响引用计数器对于实例的释放。强引用 弱引用 非占有引用 关键字 无 weak unowned 是否参与引用计数 是 否 否 let还是var let,var var let 是否optional 是(?!),否 是(?) 否 - 经典使用场景:
强引用 弱引用 非占有引用 人和房间问题 class Person {
var apartment: Apartment?
}class Apartment {
weak var tenant: Person?
}顾客和信用卡问题 class Customer {
var card: CreditCard?
}class CreditCard {
unowned let customer: Customer
}国家和首都问题 class Country {
var capitalCity: City!
}class City { unowned let country: Country }