使用所需的便利初始化解码时如何修复 "Extra argument in call"?(编码器:)?
How do I fix "Extra argument in call" when decoding with required convenience init?(coder:)?
我是应用程序开发的新手,正在尝试为使用 SwiftUI 编写的家庭作业管理应用程序添加持久性。我在我的 "UserData" class 中实现了 NSCoding 并且能够毫无问题地创建编码函数,但是在我设置解码函数之后我在 self.init() 行。我的代码究竟有什么问题?
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)
}
}
UserData
是一个 class,并且 classes 与结构不同,不会获得默认的成员初始化器。您需要创建一个接受这些参数的初始化程序。没有它,Swift 可以找到的最接近的初始化器是从 NSObject
继承的 init()
- 除了参数名称不匹配所以它给出了一个错误。
您需要创建成员初始化器:
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)
是一个失败的初始化器,所以你可以 return 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)
}
我可能会去掉分配给 courses
、username
和 appState
的默认值——您不需要它们,因为这些值将来自初始化程序
我是应用程序开发的新手,正在尝试为使用 SwiftUI 编写的家庭作业管理应用程序添加持久性。我在我的 "UserData" class 中实现了 NSCoding 并且能够毫无问题地创建编码函数,但是在我设置解码函数之后我在 self.init() 行。我的代码究竟有什么问题?
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)
}
}
UserData
是一个 class,并且 classes 与结构不同,不会获得默认的成员初始化器。您需要创建一个接受这些参数的初始化程序。没有它,Swift 可以找到的最接近的初始化器是从 NSObject
继承的 init()
- 除了参数名称不匹配所以它给出了一个错误。
您需要创建成员初始化器:
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)
是一个失败的初始化器,所以你可以 return 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)
}
我可能会去掉分配给 courses
、username
和 appState
的默认值——您不需要它们,因为这些值将来自初始化程序