init coder aDecoder究竟是什么?

时间:2016-07-15 00:55:56

标签: ios swift

我从在线课程学习iOS开发,每当我创建自定义视图(自定义表格视图单元格,集合视图单元格等)时,教师总是实现此初始化程序:

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

为什么我总是要打电话给这个?它有什么作用?我可以在init中放置属性吗?

2 个答案:

答案 0 :(得分:89)

我将从相反的方向开始这个答案:如果你想将视图的状态保存到磁盘怎么办?这称为序列化。反之亦然反序列化 - 从磁盘恢复对象的状态。

NSCoding协议定义了两种序列化和反序列化对象的方法:

encodeWithCoder(_ aCoder: NSCoder) {
    // Serialize your object here
}

init(coder aDecoder: NSCoder) {
    // Deserialize your object here
}

那为什么在你的自定义课程中需要它?答案是Interface Builder。将对象拖到故事板上并对其进行配置时,Interface Builder会将该对象的状态序列化到磁盘上,然后在故事板出现在屏幕上时对其进行反序列化。您需要告诉Interface Builder如何执行这些操作。至少,如果你没有向你的子类添加任何新属性,你可以简单地让超类为你做包装和解包,因此super.init(coder: aDecoder)调用。如果您的子类更复杂,则需要为子类添加自己的序列化和反序列化代码。

这与Visual Studio的方法形成对比,Visual Studio的方法是将代码写入隐藏文件以在运行时生成对象。

答案 1 :(得分:22)

实现初始化程序的要求是两件事的结果:

  1. Liskov substitution principle。如果S是T的子类(例如MyViewControllerViewController的子类),则S对象(MyViewController的实例)必须能够在T对象的位置替换(实例ViewController)是预期的。

  2. 如果在子类中显式定义了任何初始化程序,则不会在Swift中继承初始化程序。如果显式提供了一个初始值设定项,则必须显式提供所有其他初始值设定项(然后可以调用super.init(...))。有关基本原理,请参阅this question。它是用Java编写的,但仍然适用。

  3. 从第1点开始,原始ViewController可以做的所有事情,MyViewController子类应该能够做到。一个这样的事情是能够从给定的NSCoder初始化。到第2点,您的MyViewController子类不会自动继承此功能。因此,您必须手动提供满足此要求的初始化程序。在这种情况下,您只需要委托超类,让它做它通常会做的事情。

相关问题