2016-07-15 70 views
38

我是从网上课程学习iOS开发,每次我做一个自定义视图(自定义表视图细胞,采集观察室等)的教练始终贯彻这个初始化:init编码器aDecoder究竟是什么?

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

    } 

到底为什么总是我必须调用这个?它有什么作用?我可以将属性放入init吗?

+2

这个答案会帮助你http://stackoverflow.com/questions/24036393/fatal-error-use-of-unimplemented-initializer-initcoder-for-class谢谢 –

+0

如果你实现了一个实现了'NSCoding'的对象,那么你需要实现这个初始化器,因为它需要实现'NSCoding'的类。您至少必须调用超类init方法。如果'NSCoder'包含你的类的编码属性,那么你可以使用这种方法来恢复那些 – Paulw11

+1

尝试搜索。这个问题在这里已经被回答了很多次。 – matt

回答

7

实现一个初始化的要求是两件事情的结果:

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

  2. 如果在子类中明确定义了任何初始值设定项,则在Swift中不会继承初始值设定项。如果明确提供了一个初始化程序,则必须明确提供所有其他初始化程序(然后才可以拨打super.init(...))。基本原理见this question。它在Java中,但仍然适用。

到1点,一切原来ViewController可以做什么,MyViewController子类应该是能够做到的。一个这样的事情是能够从给定的NSCoder初始化。到了第2点,你的MyViewController子类不会自动继承这个能力。因此,您必须手动提供符合此要求的初始化程序。在这种情况下,你只需要将它委托给超类,让它做它通常会做的事情。

+0

构造函数不被继承是非常有意义的:如果使用基类的(继承)初始化方法初始化派生类的实例,那么派生类新定义(“添加”)的非继承属性将会永远不会被初始化。 –

+0

实际上,初始值设定项是在Swift中继承的,因为您没有在您的子类中提供任何自己的初始值设定项实现。如果新定义的非继承属性具有默认值,那么可以避免在子类中编写任何初始化器,并简单地继承所有超类的初始化器。见[这里](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID222) – TheBaj

+0

@TheBaj好点,我忽略了这一点。 – Alexander

45

我会从相反的方向开始回答:如果要将视图的状态保存到磁盘,该怎么办?这被称为系列化。反过来是反序列化 - 从磁盘恢复对象的状态。

NSCoding协议定义了2种方法进行序列化和反序列化对象:

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的方法形成鲜明对比,该方法将代码写入隐藏文件以在运行时创建对象。

+0

为什么不把所有内容都放在awakeFromNib中,忘记使用'init(coder aCoder:NSCoder)'? – Honey

+0

@霍尼 - 总而言之,“有时你不能那样做”。你通常可以但不总是。 – Fattie

+0

@Fattie是不是太复杂或不必知道的细节?如果你不介意解释? – Honey