我将以下Person
类符合NSCoding
协议。
class Person: NSObject, NSCoding{
var age:Int
var height: Double
var name: String
init(age:Int, height: Double, name:String){
self.age = age
self.height = height
self.name = name
}
func encode(with aCoder: NSCoder){
aCoder.encode(age, forKey: "age")
aCoder.encode(height, forKey: "height")
aCoder.encode(name, forKey: "name")
}
required init?(coder aDecoder: NSCoder){
age = aDecoder.decodeObject(forKey: "age") as! Int **//error**
height = aDecoder.decodeObject(forKey: "height") as! Double
name = aDecoder.decodeObject(forKey: "name") as! String
super.init()
}
}
然后,我创建了这个类的数组。我使用NSKeyedArchiver
将它存档到一个plist,一切都很好。但是,当我试图取消归档时,我遇到了一个错误,涉及展开一个可选的nil。错误出现在标记为Person
的类中。这是我使用的代码:
if let people = unarchive(){
print(people)
}
这里是取消归档的功能:
func unarchive()->[Person]?{
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentDirectory = paths[0]
let path = documentDirectory.appending("ObjectData.plist")
let fileManager = FileManager.default
if(!fileManager.fileExists(atPath: path)){
if let bundlePath = Bundle.main.path(forResource: "ObjectData", ofType: "plist"){
do{
try fileManager.copyItem(atPath: bundlePath, toPath: path)
}catch{
print("problem copying")
}
}
}
if let objects = NSKeyedUnarchiver.unarchiveObject(withFile: path){
if let people = objects as? [Person]{
return people
}else{
return nil
}
}else{
return nil
}
}
答案 0 :(得分:0)
Int
和Double
未归档为对象。对于aDecoder.decodeObject(forKey: <key>)
,nil
将始终返回as!
,将nil
与aDecoder.decodeInteger(forKey: "age")
aDecoder.decodeDouble(forKey: "height")
一起使用会导致您的应用崩溃。
所以,改为使用:
name
对于{{1}}字段,您可以保留代码。
答案 1 :(得分:-1)
你应该对Int和Double使用正确的解码方法。您可以将以下代码粘贴到游乐场中并进行测试:
import Foundation
class Person: NSObject, NSCoding{
var age:Int
var height: Double
var name: String
init(age:Int, height: Double, name:String){
self.age = age
self.height = height
self.name = name
}
func encode(with aCoder: NSCoder) {
aCoder.encode(age, forKey: "age")
aCoder.encode(height, forKey: "height")
aCoder.encode(name, forKey: "name")
}
required init?(coder aDecoder: NSCoder) {
age = aDecoder.decodeInteger(forKey: "age")
height = aDecoder.decodeDouble(forKey: "height")
name = aDecoder.decodeObject(forKey: "name") as! String
super.init()
}
}
let john = Person(age: 30, height: 170, name: "John")
let mary = Person(age: 25, height: 140, name: "Mary")
let guys = [john, mary]
let data = NSKeyedArchiver.archivedData(withRootObject: guys)
let people = NSKeyedUnarchiver.unarchiveObject(with: data)
dump (people)