一步步学习Swift

Swift的初始化

2020-08-14  本文已影响0人  冷武橘

一、初始化器

  init(weidth:Int,height:Int) {

    }

1、指定初始化器是主要的初始化器,每个类至少有一个指定初始化器。
2、默认初始化器总是类的指定初始化器。
3、类偏向于少量指定初始化器。

 convenience init(width:Int) {

    }

便捷初始化器是次要的,为一个类支持初始化器。

二、初始化器的相互调用

规则1

1、便捷初始化器最终必须调用一个指定初始化器。

class Person {

    init(age:Int) {
       print(“运行”)
    }

    convenience init(){
        self.init(age:20)
    }
}
class Person {
    init(age:Int) {
    
    }
    convenience init(){
        self.init(score:40)
    }
    convenience init(score:Int){
        self.init(age:20)
    }
}

规则2

2、指定初始化器必须从它的直系父类调用指定初始化器。

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

class student :Person{
    init(height:Int) {
        super.init(age: 20)
    }
}
屏幕快照 2019-07-23 下午6.23.33.png 截屏2020-08-14 上午10.45.35.png
规则3

3、便捷初始化器必须从相同的类里调用另一个初始化器。


屏幕快照 2019-07-23 下午6.29.58.png

student类和Person类是不同类,这里子类便捷初始化器直接调用父类的指定初始化器是不允许的


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

class student :Person{
    init(height:Int) {
        super.init(age: 20)
    }
    convenience init(weight:Int){
        self.init(height:60)
    }
}
屏幕快照 2019-07-23 下午6.40.52.png 屏幕快照 2019-07-23 下午6.41.23.png

三、初始化安全

Swift编译器执行四种有效的安全检查来确保两段式初始化过程能够顺利完成:

安全检查:

以下是两段初始化过程,基于上述四种检查的流程:

两段式初始化:

第1阶段:初始化所有存储属性
class Person {
    var age:Int
    
    init(age:Int) {
        self.age = age
    }
}

class student :Person{
    var sext:String
    var weight:Int
    
    init(height:Int) {
       //3.确保当前类定义的存储属性都初始化
        self.sext = “男”
        self.weight = 80

       //4.指定初始化器调用父类的初始化器,不断向上调用,形成初始化器链。
        super.init(age: 20)
    }
}

//1.外部调用指定初始化器
let s = student(height: 20)
//2.分配内存给实例
第2阶段:设置新的存储属性值
lass Person {
    var age:Int
    init(age:Int) {
        self.age = age
      //1、顶部初始化器开始,调用它的实例方法
        self.test()
    }
    
    func test() {
        print(“test”)
    }
}

class student :Person{
    var sext:String
    var weight:Int
    init(height:Int) {
        self.sext = “男”
        self.weight = 80
        super.init(age: 20)

    //2、修改它的属性
        self.age = 23
    }

   convenience init(score:Int){
        self.init(height: 20)

  //2、修改它的属性
        self.age = 33
        self.test()
    }
}
let s = student(height: 20)

四、总结

五、可失败初始化器

类、结构体、枚举都可以用init?定义可失败初始化器

5.1 、定义可失败初始化器

struct Person {
    init?(name:String) {
        if name.isEmpty {
            print("初始化失败")
            return nil
        }
    }
}
class Person {
    init!(name:String) {
        if name.isEmpty {
            print("初始化失败")
            return nil
        }
    }
}
let p = Person(name: "eee")
print(p!)

init!定义隐式解包的一个可失败初始化器,在上面的例子无法体现区别。在下面的例子就可以感受到。

5.2、

class Person {
    convenience init!(name:String) {
        if name.isEmpty {
            print("初始化失败")
            return nil
        }
        self.init()
    }
    init() {
        
    }
}

可失败初始化器可以调用非可失败初始化器

class Person {
     init?(name:String) {
        if name.isEmpty {
            print("初始化失败")
            return nil
        }
       
    }
   convenience  init() {
    self.init(name:"")!
    }
}


class Person {
     init!(name:String) {
        if name.isEmpty {
            print("初始化失败")
            return nil
        }
       
    }
   convenience  init() {
    self.init(name:"")
    }
}

六、反初始化器(deinit)

deinit叫做反初始化器,类似于c++的析构函数、OC中的delloc方法


class Person {
    deinit {
        print("Person对象销毁了")
    }
}
var p:Person?  = Person()
p = nil
上一篇 下一篇

猜你喜欢

热点阅读