为了账号安全,请及时绑定邮箱和手机立即绑定

Swift 3从userDefaults保存和检索自定义对象

Swift 3从userDefaults保存和检索自定义对象

潇潇雨雨 2019-10-16 14:53:24
我在Playground中使用Swift 3,Xcode 8.0拥有此功能:import Foundationclass Person: NSObject, NSCoding {    var name: String    var age: Int    init(name: String, age: Int) {        self.name = name        self.age = age    }    required convenience init(coder aDecoder: NSCoder) {        let name = aDecoder.decodeObject(forKey: "name") as! String        let age = aDecoder.decodeObject(forKey: "age") as! Int        self.init(            name: name,            age: age        )    }    func encode(with aCoder: NSCoder) {        aCoder.encode(name, forKey: "name")        aCoder.encode(age, forKey: "age")    }}创建人员数组let newPerson = Person(name: "Joe", age: 10)var people = [Person]()people.append(newPerson)编码数组let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)print("encodedData: \(encodedData))")保存到用户默认值let userDefaults: UserDefaults = UserDefaults.standard()userDefaults.set(encodedData, forKey: "people")userDefaults.synchronize()校验print("saved object: \(userDefaults.object(forKey: "people"))")从userDefaults返回if let data = userDefaults.object(forKey: "people") {    let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data as! Data)    print("myPeopleList: \(myPeopleList)")}else{    print("There is an issue")}只需检查存档的数据if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){   print("myPeopleList: \(myPeopleList)")}else{   print("There is an issue")}我无法正确将数据对象保存到userDefaults,此外,底部的检查还会产生错误“严重错误:在展开可选值时意外发现nil”。“检查”行还显示已保存的对象为nil。这是我对象的NSCoder中的错误吗?
查看完整描述

3 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

let age = aDecoder.decodeObject(forKey: "age") as! Int

Swift 3对此进行了更改;这不再适用于值类型。现在正确的语法是:


let age = aDecoder.decodeInteger(forKey: "age")

有针对各种不同类型的关联的encode ...()函数:


let myBool = aDecoder.decodeBoolean(forKey: "myStoredBool")

let myFloat = aDecoder.decodeFloat(forKey: "myStoredFloat")

编辑:Swift 3中所有可能的encodeXXX函数的完整列表


编辑:


另一个重要的注意事项:如果您以前保存过使用较早版本的Swift编码的数据,则必须使用encodeObject()解码这些值,但是一旦使用encode(...)重新编码数据,就不能再使用如果它是值类型,则使用decodeObject()解码。因此,Markus Wyss的答案将允许您处理使用两种Swift版本对数据进行编码的情况:


self.age = aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")


查看完整回答
反对 回复 2019-10-16
  • 3 回答
  • 0 关注
  • 817 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信