swift - 为什么在执行 NSCoding 时不会保存对类变量的更改

标签 swift nscoding

这是我尝试使用 NSEncoding 进行编码的自定义类的代码。变量 currentLesson 未初始化。

class UserData: NSObject, NSCoding {
    var race: [String]
    var religion: [String]
    var sexualOrientation: [String]
    var gender: [String]

    var currentLesson: Int

    static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
    static let ArchiveURL = DocumentsDirectory.appendingPathComponent("user")

    struct PropertyKey {
        static let nameKey = "name"
        static let race = "race"
        static let religion = "religion"
        static let sexualOrientation = "sexualOrientation"
        static let gender = "gender"

        static let currentLesson = "currentLesson"
    }

    init?(raceArray: [String], religionArray: [String], sexualOrientationArray: [String], genderArray: [String]) {

        self.race = raceArray
        self.religion = religionArray
        self.sexualOrientation = sexualOrientationArray
        self.gender = genderArray

        self.currentLesson = 0

        super.init()
    }

    // NSCoding

    func encode(with aCoder: NSCoder) {
        aCoder.encode(race, forKey: PropertyKey.race)
        aCoder.encode(religion, forKey: PropertyKey.religion)
        aCoder.encode(sexualOrientation, forKey: PropertyKey.sexualOrientation)
        aCoder.encode(gender, forKey: PropertyKey.gender)

        aCoder.encode(currentLesson, forKey: PropertyKey.currentLesson)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        let race = aDecoder.decodeObject(forKey: PropertyKey.race) as! [String]
        let religion = aDecoder.decodeObject(forKey: PropertyKey.religion) as! [String]
        let sexualOrientation = aDecoder.decodeObject(forKey: PropertyKey.sexualOrientation) as! [String]
        let gender = aDecoder.decodeObject(forKey: PropertyKey.gender) as! [String]

        self.init(raceArray: race, religionArray: religion, sexualOrientationArray: sexualOrientation, genderArray: gender)
    }
}

现在,这是我尝试更改 currentLesson 变量的代码:

let user = NSKeyedUnarchiver.unarchiveObject(withFile: UserData.ArchiveURL.path) as? UserData
print(user!.currentLesson)

user?.currentLesson = 1
print(user!.currentLesson)

NSKeyedArchiver.archiveRootObject(user!, toFile: UserData.ArchiveURL.path)

let user2 = NSKeyedUnarchiver.unarchiveObject(withFile: UserData.ArchiveURL.path) as? UserData
print(user2!.currentLesson)

但是,正如我从打印语句 (0/n 1/n 0) 中可以看出的,currentLesson var 没有更新。为什么是这样?我很困惑如何更改它并保存它而不使其成为初始化值之一。

最佳答案

您对currentLesson进行编码,但不对其进行解码。您不会尝试在 init(coder:) 初始值设定项中获取编码值。因此,当您调用另一个 init 时,它会重置回 0

您需要更新您的 init 方法。以下内容应该有效(请注意新 currentLesson 参数的默认值):

init?(raceArray: [String], religionArray: [String], sexualOrientationArray: [String], genderArray: [String], currentLesson: Int = 0) {
    self.race = raceArray
    self.religion = religionArray
    self.sexualOrientation = sexualOrientationArray
    self.gender = genderArray

    self.currentLesson = currentLesson

    super.init()
}

required convenience init?(coder aDecoder: NSCoder) {
    let race = aDecoder.decodeObject(forKey: PropertyKey.race) as! [String]
    let religion = aDecoder.decodeObject(forKey: PropertyKey.religion) as! [String]
    let sexualOrientation = aDecoder.decodeObject(forKey: PropertyKey.sexualOrientation) as! [String]
    let gender = aDecoder.decodeObject(forKey: PropertyKey.gender) as! [String]
    let currentLesson = aDecoder.decodeInteger(forKey: PropertyKey.currentLesson)

    self.init(raceArray: race, religionArray: religion, sexualOrientationArray: sexualOrientation, genderArray: gender, currentLesson: currentLesson)
}

关于swift - 为什么在执行 NSCoding 时不会保存对类变量的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44319952/

相关文章:

swift - [Card] 类型的不可变值仅具有名称追加的可变值

ios - 初始化器不会覆盖其父类(super class)中的指定初始化器

ios - Swift 主从模板问题(iOS 8 beta 3)

Objective-C - 只读 NSMutableArray 和 NSCoding?

ios - 如何使用MDCardCollectionCell? [iOS Material 组件]

ios - 如何在 ios swift 中从原型(prototype)单元获取数据到 Controller 并从中更新模型

ios - 尝试在 Swift 3 中保存自定义对象时尝试插入非属性列表对象

ios - 在 Swift 中归档自定义对象 - 扩展

ios - 是否可以使用encodeObject来存档UIPickerView?

swift - Swift 3 中的 NSCoding - 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因 : '-[AppName. 用户encodeWithCoder:]