【问题标题】:Save Dictionary of custom objects in Swift using UserDefaults使用 UserDefaults 在 Swift 中保存自定义对象的字典
【发布时间】:2018-05-30 03:51:09
【问题描述】:

我正在编写一个应用程序来处理联系人,并尝试使用 UserDefaults 保存信息,但我得到了 SIGABRT。这是我的代码,我做错了什么?

class Contact{
var name = String()
var phone = String()

init(name: String, phone: String){
    self.name=name
    self.phone=phone
}
required init(coder decoder: NSCoder){
    self.name = (decoder.decodeObject(forKey: "name") as? String)!
    self.phone = (decoder.decodeObject(forKey: "phone") as? String)!
}
func encode(with coder: NSCoder){
    coder.encode(name, forKey: "name")
    coder.encode(phone, forKey: "phone")
}
}

在 ViewDidLoad 中创建联系人只是为了测试:

        let userDefaults = UserDefaults.standard
var contactDictionary = Dictionary<String, [Contact]>()

  override func viewDidLoad() {
    super.viewDidLoad()
    contactDictionary["A"] = [Contact(name: "Annabel",phone: "000")]

    let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
    userDefaults.set(encodedData, forKey: "contactDictionary")
    userDefaults.synchronize()
    if let data = userDefaults.data(forKey: "contactDictionary"){
        print("yep")
        contactDictionary = (NSKeyedUnarchiver.unarchiveObject(with: data) as? [String : [Contact]])!
    }
    else{
        print("nope")
    }
}

【问题讨论】:

  • 您需要使您的类NSCoding 兼容并从NSObject 继承。将您的联系人声明更改为class Contact: NSObject, NSCoding {。顺便说一句,有条件地强制在以后打开它是没有意义的。 decoder.decodeObject(forKey: "name") as! String
  • 关于强制展开,这里同样适用NSKeyedUnarchiver.unarchiveObject(with: data) as! [String : [Contact]]
  • 没有帮助,得到相同的 SIGABRT,它正在写:Unrecognized selector -[Contacts.Contact replacementObjectForKeyedArchiver:]
  • 我已经在这里测试过了,它可以工作。编辑您的问题并添加您的实际代码
  • 谢谢你,我会努力解决的

标签: swift nsuserdefaults userdefaults


【解决方案1】:

您需要使您的类 NSCoding 兼容并从 NSObject 继承。将您的联系人声明更改为联系人类:NSObject, NSCoding {.顺便说一句,有条件地强制在以后打开它是没有意义的。 decoder.decodeObject(forKey: "name") as! String

class Contact: NSObject, NSCoding {
    var name = String()
    var phone = String()
    init(name: String, phone: String){
        self.name=name
        self.phone=phone
    }
    required init(coder decoder: NSCoder){
        self.name = decoder.decodeObject(forKey: "name") as! String
        self.phone = decoder.decodeObject(forKey: "phone") as! String
    }
    func encode(with coder: NSCoder){
        coder.encode(name, forKey: "name")
        coder.encode(phone, forKey: "phone")
    }
}

测试:

let contactDictionary = ["A":[Contact(name: "Annabel",phone: "000")]]

let encodedData = NSKeyedArchiver.archivedData(withRootObject: contactDictionary)
UserDefaults.standard.set(encodedData, forKey: "contactDictionary")

if let data = UserDefaults.standard.data(forKey: "contactDictionary") {
    print("yep")
    let contactDictionary2 = NSKeyedUnarchiver.unarchiveObject(with: data) as! [String : [Contact]]
}
else{
    print("nope")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2016-10-25
    • 2018-10-03
    相关资源
    最近更新 更多