【发布时间】:2017-06-24 22:25:26
【问题描述】:
我有一些我想解码的键,但它只解码我的第一个字符串,然后它给出了错误。
class Profile: NSCoder, NSCoding {
struct Constants {
// Age
static let minimumAge: Int = 5
static let maximumAge: Int = 120
static let defaultAge: Int = 25
// Gender
static let defaultGender: Int = 0
// Daily meals
static let defaultDailyMeals: Int = 3
static let minimumDailyMeals: Int = 1
static let maximumDailyMeals: Int = 10
// Do you train
static let defaultIsTraining: Bool = false
}
//MARK: Properties
private var name: String
private var age: Int
private var gender: Int
private var target: Int
private var dailyMeals: Int
private var isTraining: Bool
private var trainingWhen: Int?
private var trainingDays: [(Int)];
//MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("profile")
//MARK: Types
struct PropertyKey {
static let name = "profileName"
static let age = "profileAge"
static let gender = "profileGender"
static let target = "profileTarget"
static let dailyMeals = "profileDailyMeals"
static let isTraining = "profileIsTraining"
static let trainingWhen = "profileTrainingWhen"
static let trainingDays = "trainingDays"
}
// Main init
init?(name: String, age: Int, gender: Int, target: Int, dailyMeals: Int, isTraining: Bool, trainingWhen: Int?, trainingDays: [(Int)]) {
guard !name.isEmpty else {
print("Name empty")
return nil
}
guard age > Constants.minimumAge && age < Constants.maximumAge else {
print("Age not in range")
return nil
}
self.name = name
self.age = age
self.gender = gender
self.target = target
self.dailyMeals = dailyMeals
self.isTraining = isTraining
self.trainingWhen = trainingWhen
self.trainingDays = trainingDays
}
//MARK: NSCoding
func encode(with aCoder: NSCoder) {
aCoder.encode(self.name, forKey: PropertyKey.name)
aCoder.encode(self.age, forKey: PropertyKey.age)
aCoder.encode(self.gender, forKey: PropertyKey.gender)
aCoder.encode(self.target, forKey: PropertyKey.target)
aCoder.encode(self.dailyMeals, forKey: PropertyKey.dailyMeals)
aCoder.encode(self.isTraining, forKey: PropertyKey.isTraining)
aCoder.encode(self.trainingWhen, forKey: PropertyKey.trainingWhen)
aCoder.encode(self.trainingDays, forKey: PropertyKey.trainingDays)
}
func dump_data(){
print("Name: " + self.name)
print("Age: " + String(self.age))
print("Gender: " + String(self.gender))
print("Target: " + String(self.target))
print("Daily Meals: " + String(self.dailyMeals))
print("Does train?: " + String(self.isTraining))
print("When: " + String(describing: self.trainingWhen))
print("Days: " + String(describing: self.trainingDays))
}
required convenience init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
print("Unable to decode the name for a Profile object.")
return nil
}
print("Decoded: Name - \(name)")
guard let age = aDecoder.decodeObject(forKey: PropertyKey.age) as? Int else {
print("Unable to decode the age for a Profile object.")
return nil
}
guard let gender = aDecoder.decodeObject(forKey: PropertyKey.gender) as? Int else {
print("Unable to decode the gender for a Profile object.")
return nil
}
guard let target = aDecoder.decodeObject(forKey: PropertyKey.target) as? Int else {
print("Unable to decode the target for a Profile object.")
return nil
}
guard let dailyMeals = aDecoder.decodeObject(forKey: PropertyKey.dailyMeals) as? Int else {
print("Unable to decode the daily meals for a Profile object.")
return nil
}
guard let isTraining = aDecoder.decodeObject(forKey: PropertyKey.isTraining) as? Bool else {
print("Unable to decode the training state for a Profile object.")
return nil
}
let trainingWhen: Int? = aDecoder.decodeObject(forKey: PropertyKey.trainingWhen) as? Int ?? nil
let trainingDays: [(Int)] = aDecoder.decodeObject(forKey: PropertyKey.trainingDays) as? [(Int)] ?? []
// Must call designated initializer.
self.init(name: name, age: age, gender: gender, target: target, dailyMeals: dailyMeals, isTraining: isTraining, trainingWhen: trainingWhen, trainingDays: trainingDays)
}
我得到的错误信息是
无法解码 Profile 对象的年龄。
只要我知道这意味着我的aDecoder.decodeObject(forKey: PropertyKey.gender) 为? Int 返回 nil,我完全不知道为什么会发生这种情况,因为我对它进行了编码,正如您在代码中看到的那样。 :/
【问题讨论】:
-
如果你想让你的对象符合 NSCoding,那么你不应该从 NSCoder 而是从 NSObject 派生这个对象
标签: swift nskeyedarchiver