Swift-04-Designated&&Convenience

class ClassA {
    let numA:Int
    init(num: Int){
        numA = num
    }
}

class ClassB: ClassA {
    let numB:Int
    override init(num: Int) {
        numB = num + 1
        super.init(num: num)
    }
}

  我们可以在init里面对let的实例变量进行赋值,这是初始化方法的重要特点。在Swift中,let声明的值是不变量,无法被写入赋值,这对构建线程安全的API十分有用。而因为init只可能被调用一次,因此在init中我们可以为不变量进行赋值,而不会引起任何线程安全的问题。

与designated初始化方法对应的是在init方法前加上convenience关键字的初始化方法。这类方法是Swift初始化方法中的“二等公民”,只作为补充和提供使用上的方便。所有的convenience初始化方法都必须调用同一个类中的designated初始化完成设置,另外convenience的初始化方法是不能被子类重写或者是从子类中以super的方式被调用的。

class ClassA {
    let numA:Int
    init(num:Int){
        numA = num
    }
    
    convenience init(bigNum: Bool){
        self.init(num: bigNum ? 10000 : 1)
    }
}

class ClassB: ClassA {
    let numB: Int
    override init(num: Int) {
        numB = num + 1
        super.init(num: num)
    }
}

  添加了convenience方法了。。

  只要在子类中实现重写了父类的convenience方法所需要的init方法,我们在子类中就也可以使用父类的convenience初始化方法了。

  现在我们打印一下:

let anObj = ClassB(bigNum: true)
print(anObj.numA)

let a = ClassB.init(num: 1)
print(a.numB)

  1.初始化路径必须保证对象完全初始化,这可以通过调用本类型的designated初始化方法来得到保证;

  2.子类的designa初始化方法必须调用父类的designated方法,以保证父类也完成初始化

对于某些我们希望子类中一定实现的designated初始化方法,我们可以通过添加required关键字进行限制,强制子类对这个方法重写实现。这样的好处就是可以保证依赖于某个designated初始化方法的convenience一直可以被使用。比如init(bigNum: Bool):,如果我们希望这个初始化方法对于子类一定可用,那么就将init(num: Int)声明为必须,这样我们在子类调用init(bigNum:Bool)时,就始终能找到一条完全初始化的路径了。

  

  另外需要说明是:其实不仅仅是对designated初始化方法,对于convenience的初始化方法,我们也可以加上required以确保子类对其进行实现。这在要求子类不直接使用父类中的convenience初始化方法会非常有帮助。

这篇文章,是抄的王巍前辈的。http://swifter.tips/init-keywords/

原文地址:https://www.cnblogs.com/tanglimei/p/5131275.html