NSCoding требуется инициализатор в унаследованных классах в Swift
У меня есть класс Foo, который соответствуетNSObject
а такжеNSCoding
с которой я хочу быть в состоянии упорствоватьNSKeyedArchiver
Я хочу создать класс Bar, подкласс Foo, который также будет соответствоватьNSObject
а такжеNSCoding
, У меня проблемы с пониманием, как создатьrequired convenience init?(coder aDecoder: NSCoder)
в подклассе.
так класс фу ...
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 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)
}
Я в основном скопировал инициализатор, требуемый для суперкласса, а затем добавил дополнительный метод декодирования для свойства подкласса. Этот подход не кажется правильным ...
Есть ли лучший способ реализовать это ??