必须调用超类'日'错误的指定初始值设定项

问题描述:

在我的应用程序中,我尝试使用数据持久性来保存数据,但出现此错误: 必须调用超类“日”错误的指定初始值设定项。必须调用超类'日'错误的指定初始值设定项

这里是我的代码:

class Day: NSObject, NSCoding { // NEMA NSCODING I NSOBJECT 
var dayName: String 
var subjects: [Subject]? 

init(dayName: String) { 
    self.dayName = dayName 
} 

struct PropertyKey { 
    static var dayName = "dayName" 
    static var subjects = "subjects" 
} 

func encode(with aCoder: NSCoder) { 
    aCoder.encode(dayName, forKey: PropertyKey.dayName) 
    aCoder.encode(subjects, forKey: PropertyKey.subjects) 
} 

// Archiving paths 
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first! 
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("workingDays")//-namesto meals 

required convenience init?(coder aDecoder: NSCoder) { 
    guard let dayName = aDecoder.decodeObject(forKey: PropertyKey.dayName) as? String else { 
     os_log("Unable to decode the dayName for a Day object.", log: OSLog.default, type: .debug) 
     return nil 
    } 
    let subjects = aDecoder.decodeObject(forKey: PropertyKey.subjects) as? [Subject] 
    self.init(dayName: dayName) 
} 

}

这里是其它类:

class Subject: Day { 
var subjectName: String 
var startsAt: String? 
init(dayName: String,subjectName: String) { 
    self.subjectName = subjectName 
    super.init(dayName: dayName) 
} 
required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) // here I get the error 
} 

}

我要去拯救这种方式与数据仅在Day类中实现数据持久性,为什么会出现该错误? 我是初学者,我在此基础上的苹果文档做 -

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=12&cad=rja&uact=8&ved=0ahUKEwjWoIHk4uvXAhUHaFAKHbQFCHcQFghbMAs&url=https%3A%2F%2Fdeveloper.apple.com%2Flibrary%2Fcontent%2Freferencelibrary%2FGettingStarted%2FDevelopiOSAppsSwift%2FPersistData.html&usg=AOvVaw24H5Uo4RyRY7NYIlztlgCj

任何帮助将非常感激。

问题是由在Dayinit?(coder调用self.init引起。该调用使初始化程序convenient和子类不能满足调用指定初始化程序的要求。

的解决方案是初始化属性直接

required init?(coder aDecoder: NSCoder) { 
    self.dayName = aDecoder.decodeObject(forKey: PropertyKey.dayName) as! String 
    self.subjects = aDecoder.decodeObject(forKey: PropertyKey.subjects) as? [Subject] 
} 

顺便说一句:你总是dayName编码非可选字符串,所以它永远不能nil被解码的时候。 guard是无用的。

在子类中,您可能需要添加代码来解码/解码子类的属性,并调用super来考虑超类的属性。

class Subject: Day { 
    var subjectName: String 
    var startsAt: String? 

    init(dayName: String, subjectName: String) { 
     self.subjectName = subjectName 
     super.init(dayName: dayName) 
    } 

    override func encode(with aCoder: NSCoder) { 
     super.encode(with: aCoder) 
     aCoder.encode(subjectName, forKey: "subjectName") 
     aCoder.encode(startsAt, forKey: "startsAt") 
    } 

    required init?(coder aDecoder: NSCoder) { 
     subjectName = aDecoder.decodeObject(forKey: "subjectName") as! String 
     startsAt = aDecoder.decodeObject(forKey: "startsAt") as? String 
     super.init(coder: aDecoder) 
    } 
} 

使用一个子类作为其超类属性的意义的问题则是另一回事

+0

其实现在我不确定这段代码会做什么。它会永久保存这些类的数据还是必须编写一些其他代码才能做到这一点。感谢我在这里的帮助,我很新。 –

所要求Initializers-的定义:

Write the required modifier before the definition of a class initializer to indicate that every subclass of the class must implement that initializer:

You do not write the override modifier when overriding a required designated initializer:

你的情况,你做的超requiredconvenience initialiser,所以子类必须现在就实现它 - :

代码修正 - :

class Subject: Day { 
    var subjectName: String 
    var startsAt: String? 
    init(dayName: String,subjectName: String) { 
     self.subjectName = subjectName 
     super.init(dayName: dayName) 
    } 

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


} 
+0

我想这样做,我得到那个致命错误“的init(编码器:)尚未实现” .. –