初始化编码器aDecoder到底是什么?


122

我正在从在线课程中学习iOS开发,每次我创建自定义视图(自定义表格视图单元格,集合视图单元格等)时,讲师始终会实现此初始化程序:

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

为什么我总是必须打电话给我?它有什么作用?我可以将属性放入init吗?



2
如果您将实现的对象子类化,NSCoding则您需要实现此初始化程序,因为实现类是必需的NSCoding。您至少必须调用超类的init方法。如果NSCoder包含您的类的编码属性,则可以使用此方法恢复那些
属性

1
另外,我建议您阅读Apple官方Swift书中有关对象初始化的部分。
Nicolas Miari '16

Answers:


121

我将从相反的方向开始这个答案:如果要将视图状态保存到磁盘该怎么办?这称为序列化。反之则是反序列化 -从磁盘还原对象的状态。

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的方法是将代码写入隐藏文件中,以在运行时创建对象。


为什么不将所有内容都放入awakeFromNib并忘记使用init(coder aCoder : NSCoder)呢?
亲爱的

@Honey-简而言之,“有时您无法做到”。您通常可以但并非总是如此。
Fattie

@Fattie的详细信息不是太复杂或不必要知道吗?如果不是,您介意解释吗?
蜂蜜

9
如果要在Interface Builder中配置对象,则@Honey awakeFromNib将不起作用。awakeFromNib运行时调用。您在Interface Builder中所做的任何事情都是在设计时进行的。为了完成你在做些什么设计时间运行时间encodeWithCoder(保存)和init(coder:)(装载)
代码的不同

3
@Honey,如果您不使用Interface Builder来配置您的自定义类(即使用代码以编程方式执行),则可以使用以下代码awakeFromNibinitWIthFrame
编码不同:

28

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

  1. 里氏替换原则。如果S是T的子类(例如MyViewController是的子类ViewController),则MyViewController必须在ViewController期望T个对象(的实例)中替换S对象(的实例)。

  2. 如果在子类中显式定义了任何初始化器,则在Swift中不会继承初始化器。如果显式提供了一个初始化程序,则必须显式提供所有其他初始化程序(然后可以调用super.init(...))。见此问题的理由。它使用Java,但仍然适用。

通过第1点,原始类ViewController可以做的一切,MyViewController子类都应该可以做。这样的事情就是能够从给定的初始化NSCoder。到第二点,您的MyViewController子类不会自动继承此功能。因此,您必须手动提供满足此要求的初始化程序。在这种情况下,您只需要委托超类,以使其能够执行通常的工作即可。


1
最好不要继承构造函数:如果您使用基类的(继承的)初始化程序初始化派生类的实例,则派生类新定义(“添加”)的非继承属性将永远不会被初始化。
Nicolas Miari '16

3
实际上,假设您没有在子类中提供任何自己的初始化器实现,则初始化器是在Swift中继承的。如果新定义的非继承属性具有默认值,则可以不用在子类中编写任何初始化程序,而直接继承所有超类的初始化程序即可。看到这里
TheBaj
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.