美文网首页
Swift 初始化

Swift 初始化

作者: Arthur澪 | 来源:发表于2020-02-20 14:18 被阅读0次

初始化器initializer

类、结构体、枚举都可以定义初始化器,类似init方法。

类的初始化

类有2种初始化器:
指定初始化器(designated initializer)
便捷初始化器(convenience initializer)

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

每个类至少有一个指定初始化器,它是类的默认初始化器、主要初始化器
一个类通常只有一个指定初始化器。偏向于少量 。

  • 相互调用规则
    指定初始化器必须从它的直系父类调用指定初始化器
    便捷初始化器必须从相同的类里调用另一个初始化器
    便捷初始化器最终必须调用一个指定初始化器,为了保证安全,保证所有属性都被初始化。
class Person {
    var name: String
    var age: Int
    var height: Int {
        get {
            return age * 10;
        }
    }
    // 指定初始化器
    init(name: String, age: Int) {
        self.name = name;
        self.age = age;
    }
    
    // 以下是 便捷初始化器
    convenience init(name: String){
        self.init(name: name, age: 0);
    }
 
    convenience init (age: Int) {
        self.init(name: "", age: age);
    }
 
    convenience init(){
        self.init(name: "", age: 0);
    }
}

var ppp = Person(age: 10);
var ppp1 = Person(name: "Alex");
var PPP2 = Person(name: "alex", age: 10);

Swift在编码安全方面是煞费苦心,为了保证初始化过程的安全,设定了两段式初始化、 安全检查。

-

安全检查

-

重写init

当重写父类的指定初始化器时,都必须加上override
如果子类写了一个匹配父类便捷初始化器的初始化器,不用加override
严格来说,子类无法重写父类的便捷初始化器。因为父类的便捷初始化器永远不会通过子类直接调用。

自动继承

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

required

required修饰指定初始化器,表明其所有子类都必须实现(通过继承或者重写实现)
如果子类重写了required初始化器,也必须加上required,不用加override

属性观察器

父类的属性在它自己的初始化器中赋值,不会触发属性观察器。
但在子类的初始化器中赋值,会触发属性观察器。

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()
 

可失败初始化器

可以使用init?定义

class Person {
    var name: String
    init?(name: String) {
        if name.isEmpty  {
            return nil
        }
        self.name = name
    }
}

不允许同时定义参数标签、参数个数、参数类型相同的可失败初始化器和非可失败初始化器
可以用init!定义隐式解包的可失败初始化器
可失败初始化器可以调用非可失败初始化器,非可失败初始化器调用可失败初始化器需要进行解包
如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行
可以用一个非可失败初始化器重写一个可失败初始化器,但反过来是不行的

反初始化器(deinit)

类似于 OC中的dealloc,当类的实例对象被释放内存时,就会调用实例对象的deinit

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

deinit不接受任何参数,不能写小括号,不能自行调用
父类的deinit能被子类继承
子类的deinit实现执行完毕后会调用父类的deinit

相关文章

网友评论

      本文标题:Swift 初始化

      本文链接:https://www.haomeiwen.com/subject/bpntqhtx.html