使用所需的便捷初始化进行解码时,如何解决“调用中的额外参数”?(编码器:)?

时间:2019-10-14 00:28:40

标签: ios swift nscoding

我对应用程序开发比较陌生,正在尝试为使用SwiftUI编写的作业管理应用程序增加持久性。我在“ UserData”类中实现了NSCoding,并且能够毫无问题地创建编码函数,但是在设置解码函数后,我在self.init上收到了“调用中的额外参数'assignments'”错误( )行。我的代码到底有什么问题?

class UserData: NSObject, NSCoding, ObservableObject {

    // MARK:- Properties

    @Published var assignments: [Assignment]
    @Published var courses: [Course] = []

    @Published var username: String = ""
    @Published var appState: AppState = AppState(willPresentSplashScreen: false)

...

 // MARK:- NSCoding

    func encode(with coder: NSCoder) {
        coder.encode(assignments, forKey: PropertyKey.assignments)
        coder.encode(courses, forKey: PropertyKey.courses)
        coder.encode(username, forKey: PropertyKey.username)
        coder.encode(appState, forKey: PropertyKey.appState)
    }

    required convenience init?(coder decoder: NSCoder) {

        let assignments = decoder.decodeObject(forKey: PropertyKey.assignments) as? [Assignment]
        let courses = decoder.decodeObject(forKey: PropertyKey.courses) as? [Course]
        let username = decoder.decodeObject(forKey: PropertyKey.username) as? String
        let appState = decoder.decodeObject(forKey: PropertyKey.appState) as? AppState

        self.init(assignments: assignments, courses: courses, username: username, appState: appState)
    }
}

1 个答案:

答案 0 :(得分:0)

UserData是一个类,并且与结构不同,类不会获得默认的成员级初始化程序。您需要创建一个接受这些参数的初始化程序。如果没有它,Swift可以找到的最接近的初始化程序是从init()继承的NSObject-参数名称不匹配,因此会产生错误。

您需要创建成员级初始化程序:

init(assignments: [Assignment], courses: [Course], username: String, appState: AppState) {
    self.assignments = assignments
    self.courses = courses
    self.username = username
    self.appState = appState
}

这将给您一个错误,因为从init?(coder decoder: NSCoder)传递过来的参数需要解包,因为您有可选参数,而初始化程序不希望有可选参数。

init?(coder decoder: NSCoder)是一个失败的初始化程序,因此如果一切不正确,您可以返回nil

required convenience init?(coder decoder: NSCoder) {

        guard let assignments = decoder.decodeObject(forKey: PropertyKey.assignments) as? [Assignment],
            let courses = decoder.decodeObject(forKey: PropertyKey.courses) as? [Course],
            let username = decoder.decodeObject(forKey: PropertyKey.username) as? String,
            let appState = decoder.decodeObject(forKey: PropertyKey.appState) as? AppState else {
                return nil
        }

        self.init(assignments: assignments, courses: courses, username: username, appState: appState)
}

我可能会摆脱分配给coursesusernameappState的默认值-您不需要它们,因为这些值将来自初始化程序