目录
初始化器
required
用required修饰指定初始化器,表明其所有子类都必须实现该初始化器(通过继承或者重写实现)
如果子类重写了required初始化器,也必须加上required,不用加上override
class Person { required init() {} init(age: Int) {} } class Student: Person { init(no: Int) { super.init(age: 0) } required init() { super.init() } }
属性观察器
父类的属性在它自己的初始化器中赋值不会触发属性观察器,但在子类的初始化器中赋值会触发属性观察器
class Person { var age: Int { willSet { print("willSet", newValue) } didSet { print("didSet", oldValue, age) } } init() { self.age = 0 } } class Student: Person { override init() { super.init() self.age = 1 } }
可失败初始化器
类、结构体、枚举都可以使用init?定义可失败初始化器
class Person { var name: String init?(name: String) { if name.isEmpty { return nil } self.name = name } }
不允许同时定义参数标签、参数个数、参数类型相同的可失败初始化器和非可失败初始化器
可以用init!定义隐式解包的可失败初始化器
可失败初始化器可以调用非可失败初始化器,非可失败初始化器调用可失败初始化器需要进行解包
class Person { var name: String init?(name: String) { if name.isEmpty { return nil } self.name = name } convenience init() { self.init(name: "")! } }
如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行
可以用一个非可失败初始化器重写一个可失败初始化器,但反过来是不行的。
反初始化器(deinit)
deinit叫做反初始化器,类似于C++的析构函数、OC中的dealloc方法
当类的实例对象被释放内存时,就会调用实例对象的deinit方法
class Person { deinit { print("Person对象销毁了") } }
deinit不接受任何参数,不能写小括号,不能自行调用
父类的deinit能被子类继承
子类的deinit实现执行完毕后会调用父类的deinit
可选链(Optional Chaining)
class Car { var price = 0 } class Dog { var weight = 0 } class Person { var name: String = "" var dog: Dog = Dog() var car: Car? = Car() func age() -> Int { 18 } func eat() { print("Person eat") } subscript(index: Int) -> Int { return index } } var person: Person? = Person() var age = person?.age()//Int? Optional(18) var age1 = person!.age() // Int var name = person?.name //String? var index = person?[6] // Int?
如果可选项为nil,调用方法、下标、属性失败,结果为nil
如果可选项不为nil,调用方法、下标、属性成功,结果会被包装成可选项
如果结果本来就是可选项,不会进行再次包装
判断方法有没有调用成功:
if let age = person?.age() { // ()? print("调用age成功", age) } else { print("调用age失败") }
形成可选链:
多个?可以链接在一起
如果链中任何一个节点是nil,那么整个链就会调用失败,可选链应用的地方还是很多的,在OC里面我们通常会加很多判断以避免崩溃,在Swift里面,因为有了可选链会减少很多我们自己的判断,提高了安全性。
var dog = person?.dog // Dog? var weight = person?.dog.weight // Int? var price = person?.car?.price // Int?
var scores = [ "Jack" : [86, 82, 84], "Rose" : [79, 94, 81] ] scores["Jack"]?[0] = 100 scores["Rose"]?[2] += 10 scores["Kate"]?[0] = 88
var num1: Int? = 5 num1? = 10 // Optional(10) var num2: Int? = nil num2? = 10 // nil
var dict: [String : (Int, Int) -> Int] = [ "sum" : (+), //两个Int类型相加,返回一个Int类型 "difference" : (-) ] var result = dict["sum"]?(10, 20) // Optional(30), Int?