NSCoding需要Swift中inheritance类的初始化器

我有符合NSObjectNSCoding Foo类,我希望能够坚持NSKeyedArchiver我想创build类Bar,Foo的一个子类也将符合NSObjectNSCoding 。 我有一个问题,了解如何在子类中创buildrequired convenience init?(coder aDecoder: NSCoder)

所以classFoo …

 class Foo: NSObject, NSCoding { let identifier:String init(identifier:String) { self.identifier = identifier } override var description:String { return "Foo: \(identifier)" } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(identifier, forKey: "identifier") } required convenience init?(coder aDecoder: NSCoder) { guard let identifier = aDecoder.decodeObjectForKey("identifier") as? String else { return nil } self.init(identifier:identifier) } } 

然后是class级…

 class Bar:Foo { let tag:String init(identifier:String, tag:String) { self.tag = tag super.init(identifier: identifier) } override var description:String { return "Bar: \(identifier) is \(tag)" } } 

我可以得到这个编译通过添加以下方法来使NSCoding兼容

  override func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(tag, forKey: "tag") super.encodeWithCoder(aCoder) } 

这是有道理的,因为我打电话super.encodeWithCoder(...)重用超级使这干。 我遇到的问题是创buildrequired convenience init?(...)我似乎可以得到它编译的唯一方法是通过这样做…

  required convenience init?(coder aDecoder:NSCoder) { guard let identifier = aDecoder.decodeObjectForKey("identifier") as? String, let tag = aDecoder.decodeObjectForKey("tag") as? String else { return nil } self.init(identifier:identifier, tag:tag) } 

我基本上已经复制了超类所需的初始化器,然后为子类属性添加额外的解码方法。 这种方法似乎不正确…

有没有更好的方法来实现这个?

在您解码并分配所需的init方法中的所有子类属性之后,请调用:

 super.init(coder: aDecoder) 

我已经尝试在游乐场的代码,它只是自动添加代码,当我勾选错误的红色圆圈。

编码就像你的函数需要方便的初始化。

示例代码:

 required convenience init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 

已经想了一会儿,相信这是实施这个的正确方法。

原因是Swift执行对象初始化的方式。 便利初始值设定程序只能在self上调用所需的初始值设定项。 只有需要的初始化器才能调用super上的init

因此,初始化子类对象的唯一方法是在调用子类所需的初始化程序之前解码所有必需的初始化参数,然后调用超类初始化程序

这里是你可以复制到游乐场的代码https://gist.github.com/vorlando/dc29ba98c93eaadbc7b1