初始化、可选链

初始化器

// 指定初始化器
init(parameters) {
    statements
}
// 便捷初始化器
convenience init(parameters) {
    statements
}

初始化器的相互调用


两段式初始化


安全检查


重写


自动继承

  1. 如果子类没有自定义任何指定初始化器,它会自动继承父类所有的指定初始化器
  2. 如果子类提供了父类所有指定初始化器的实现(要么通过方式1继承,要么重写)
    • 子类自动继承所有的父类便捷初始化器
  3. 就算子类添加了更多的便捷初始化器,这些规则仍然适用
  4. 子类以便捷初始化器的形式重写父类的指定初始化器,也可以作为满足规则2的一部分

required

 class Person {
    required init() { }
    init(age: Int) { }
}

class Student : Person {
    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
    }
}

// willSet 1
// didSet 0 1
var stu = Student()

可失败初始化器

class Person {
    var name: String
    init?(name: String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
}
var num = Int("123")
public init?(_ description: String)

enum Answer : Int {
    case wrong, right
}
var an = Answer(rawValue: 1)

反初始化器(deinit)

class Person {
    deinit {
        print("Person对象销毁了")
    }
}

可选链(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 { index }
}

if let _ = person?.eat() { // ()?
    print("eat调用成功")
} else {
    print("eat调用失败")
}

var person: Person? = Person()
var age1 = person!.age() // Int
var age2 = person?.age() // Int?
var name = person?.name // String?
var index = person?[6] // Int?
 func getName() -> String { "jack" }
// 如果person是nil,不会调用getName()
person?.name = getName()
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" : (+),
    "difference" : (-)
]
var result = dict["sum"]?(10, 20) // Optional(30), Int?