如何在swift代码中保存类数组

时间:2017-07-10 13:03:33

标签: arrays swift class

我正在尝试保存一个类数组,到目前为止这是我的代码:

数组:

var person1 = person(name: "Bob", age: 22)
var person2 = person(name: "John", age: 10)
var array = [person1, person2]

自定义类:

import UIKit

class person: NSObject, NSCoding {

    var name : String
    var age : Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    required init (coder aDecoder: NSCoder) {
        name = (aDecoder.decodeObject(forKey: "name") as? String)!
        age = (aDecoder.decodeObject(forKey: "age") as? Int)!
    }

   func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(age, forKey: "age")
    }
}

保存数组:

let SavedData = NSKeyedArchiver.archivedData(withRootObject: array)

let defaults = UserDefaults.standard

defaults.set(SavedData, forKey: "myPeople")

加载数组:

let saveddata = UserDefaults.standard.object(forKey: "myPeople") as? Data

if saveddata != nil{
    array = (NSKeyedUnarchiver.unarchiveObject(with: saveddata!) as? [person])!
}

错误位于第age = (aDecoder.decodeObject(forKey: "age") as? Int)!

  

Interface Builder文件中的未知类iewripple。

2 个答案:

答案 0 :(得分:1)

你不应该强迫打开。尝试获取

required init (coder aDecoder: NSCoder) {
    name = (aDecoder.decodeObject(forKey: "name") as? String)!
    age = (aDecoder.decodeObject(forKey: "age") as? Int)!
}

替换为

required init (coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
    age = aDecoder.decodeInteger(forKey: "age")
}

获取

let saveddata = UserDefaults.standard.object(forKey: "myPeople") as? Data
if saveddata != nil{
    array = (NSKeyedUnarchiver.unarchiveObject(with: saveddata!) as? [person])!
}

替换为

if let data = UserDefaults.standard.object(forKey: "myPeople"),
    let array = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as? [person] {
    persons = array
}

我已经测试过了。代码工作正常。

let person1 = person(name: "Bob", age: 22)
let person2 = person(name: "John", age: 10)
var persons = [person1, person2]

// Save data
let data = NSKeyedArchiver.archivedData(withRootObject: persons)
let defaults = UserDefaults.standard
defaults.set(data, forKey: "myPeople")

// Load data
if let data = UserDefaults.standard.object(forKey: "myPeople"),
    let array = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as? [person] {
    persons = array
}

此外,通常将类名的第一个字母大写。您可以检查this是否有命名约定。

答案 1 :(得分:1)

发生错误是因为您正在对Int进行编码,但解码失败的object

有专门的方法decodeInteger(forKey

请遵守命名约定,即类名以大写字母开头,变量名以小写字母开头。

class Person: NSObject, NSCoding {

要解决此问题,请将init(coder方法更改为

required init(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    age = aDecoder.decodeInteger(forKey: "age")
}

强制解包该字符串是100%安全的,因为该值始终编码为非可选字符。

保存数组

let savedData = NSKeyedArchiver.archivedData(withRootObject: array)
UserDefaults.standard.set(savedData, forKey: "myPeople")

加载数组

if let savedData = UserDefaults.standard.object(forKey: "myPeople") as? Data {
    array = NSKeyedUnarchiver.unarchiveObject(with: savedData) as! [Person]
}

如果可选绑定as? Data成功,强制解包在这种情况下也是安全的。