Ios 符合NSCoding的类
我将以下Ios 符合NSCoding的类,ios,swift,plist,nscoding,file-writing,Ios,Swift,Plist,Nscoding,File Writing,我将以下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
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,一切正常。然而,当我试图取消归档时,我得到了一个错误,它涉及到打开一个可选文件,该文件为零。错误出现在标记的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
}
}
Int
和Double
不作为对象存档aDecoder.decodeObject(forKey:)
对于它们将始终返回nil
,并使用作为代码>为nil
将使你的应用程序崩溃
因此,请使用以下方法:
aDecoder.decodeInteger(forKey: "age")
aDecoder.decodeDouble(forKey: "height")
对于name
字段,您可以保留您的代码。Int
和Double
不作为对象存档aDecoder.decodeObject(forKey:)
对于它们将始终返回nil
,并使用作为代码>为nil
将使你的应用程序崩溃
因此,请使用以下方法:
aDecoder.decodeInteger(forKey: "age")
aDecoder.decodeDouble(forKey: "height")
对于name
字段,您可以保留您的代码。您应该使用正确的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)
对于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)