初始编码器aDecoder究竟是什么?

我正在从在线课程学习iOS开发,每次我制作一个自定义视图(自定义表格视图单元格,集合视图单元格等)时,教师始终实现此初始化器:

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

为什么我总是不得不打电话给这个? 它有什么作用? 我可以把属性内的init?

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

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

 encodeWithCoder(_ aCoder: NSCoder) { // Serialize your object here } init(coder aDecoder: NSCoder) { // Deserialize your object here } 

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

这与Visual Studio的方法相反,即将代码写入隐藏文件以在运行时创build对象。

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

  1. Liskov替代原则 。 如果S是T的子类(例如, MyViewControllerViewController的子类),则S对象( MyViewController实例)必须能够replaceT对象( ViewController实例)的位置。

  2. 如果在子类中明确定义了任何初始值设定项,则初始值设定项不会在Swift中inheritance。 如果明确提供了一个初始化程序,则必须显式提供所有其他的初始化程序(然后才可以调用super.init(...) )。 看到这个问题的理由。 它在Java中,但仍然适用。

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