NSCoding 在 Swift 的继承类中需要初始化器
Posted
技术标签:
【中文标题】NSCoding 在 Swift 的继承类中需要初始化器【英文标题】:NSCoding required initializer in inherited classes in Swift 【发布时间】:2015-10-30 22:03:17 【问题描述】:我有符合 NSObject
和 NSCoding
的类 Foo 我希望能够坚持使用 NSKeyedArchiver
我想创建类 Bar,它是 Foo 的子类,它也将符合 NSObject
和 @ 987654325@。我在理解如何在子类中创建 required convenience init?(coder aDecoder: NSCoder)
时遇到问题。
所以类Foo...
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)
然后类 Bar ...
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(...)
重用超级使这个干燥。我遇到的问题是创建required 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)
我基本上已经复制了超类所需的初始化程序,然后为子类属性添加了额外的解码方法。这种方法似乎不正确...
有没有更好的方法来实现这个?
【问题讨论】:
super.init(coder: aDecoder)
【参考方案1】:
在所需的 init 方法中解码并分配所有子类属性后,立即调用:
super.init(coder: aDecoder)
【讨论】:
不完全确定您要将呼叫添加到super.init(coder:aDecoder)
的位置,请提供更多详细信息.. 谢谢
here is a link to an example【参考方案2】:
已经考虑了一段时间,并相信这是实现这一点的正确方法。
原因在于 Swift 强制对象初始化的方式。便利初始化器只能在self
上调用所需的初始化器。只有所需的初始化程序才能在super
上调用init
。
因此,初始化子类对象的唯一方法是在调用子类所需初始化程序之前解码所有必需的初始化参数...然后调用超类初始化程序
这是您可以复制到游乐场https://gist.github.com/vorlando/dc29ba98c93eaadbc7b1的代码
【讨论】:
您好,请给我的答案打分的人提供解释...谢谢【参考方案3】:我在 Playground 中尝试过您的代码,当我勾选错误的红色圆圈时,它只是自动添加代码。
编码就像你的函数需要方便初始化。
示例代码:
required convenience init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
【讨论】:
这解决了为编译程序而需要初始化程序的问题。仍然需要实现便利初始化程序,否则当您尝试解码存档对象时,您将生成fatalError
。 NSKeyedUnarchiver.unarchiveObjectWithFile(_:)
以上是关于NSCoding 在 Swift 的继承类中需要初始化器的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中 SKProduct 的 NSCoding 错误
如何在 Swift 的 NSCoding 初始化中返回预先存在的核心数据对象?