覆盖init和所需的init之间的区别? - 迅速

Blu*_*Boy 12 ios swift

我有时会看到一个像这样的视图,在两个不同的init方法中有相同的setup()函数.init方法之间有什么区别,为什么在两个中调用相同的setup()?

class BigButton: UIButton {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }

    fileprivate func setup() {
        // set up stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

gio*_*shc 12

override init(frame: CGRect) 以编程方式创建视图(在本例中为按钮)时使用.

required init?(coder: NSCoder) 从storyboard/xib创建视图时使用.

因为后者是必需的,你必须实施它的身体.但是,如果您不打算手动创建按钮,则不需要第一个按钮,可以省略

两者都调用了setup,因为无论您选择创建按钮,都要设置其自定义行为,以便按预期工作


Hex*_*ire 6

当您override使用诸如之类的初始化器时init(frame: CGRect),您需要对指定的初始化器(即负责通过程序创建对象的主体初始化器)进行操作。根据规则,您必须super.init 执行任何其他初始化操作之前调用。

另一方面,所需的初始化器与指定的初始化器不同。

必需的初始化器

在定义类初始化器之前编写所需的修饰符,以指示该类的每个子类都必须实现该初始化器。

您还必须在所需的初始化程序的每个子类实现之前编写required修饰符,以指示初始化程序要求适用于链中的其他子类。覆盖必需的指定初始值设定项时,请勿编写override修饰符。

资料来源:有关初始化程序的Apple文档

如果原始类的初始构造器标记为必需,则实现子类时无论实现意愿,都可以实现所需的初始构造器。通常,尽管在某些情况下,您不应该直接调用它来创建对象。必需的初始化器已标记为必须符合几个良好的要求。例如, required init?(coder: NSCoder)在几种情况下被称为。一种情况:从IB创建视图时。另一种情况-创建对象时,或者手动取消归档(称为反序列化)。实际上,当您将该对象放置到ViewController的视图上时(例如),该对象也是未存档的,即获取并设置了其所有属性。

显然,当您创建某个视图的子类时,应该使它支持此接口,该接口提供反序列化功能(以防某个时候从Interface Builder或两者之一使用它)。这就是为什么required