如何将 NSCoding 应用于 class?
How to apply NSCoding to a class?
我有以下class。当我尝试像这样将它添加到 NSUserDefaults 时:
let testClass = TestClass()
testClass.Property1 = 22.3
NSUserDefaults.standardUserDefaults().setObject(testClass, forKey: "object1")
我收到一个错误:
'NSInvalidArgumentException', reason: 'Attempt to insert non-property
list object for key object1'
class TestClass: NSObject, NSCoding {
var Property1:Double?
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
if let priceCoded = aDecoder.decodeObjectForKey("Property1") as? Double {
self.Property1 = priceCoded
}
}
func encodeWithCoder(aCoder: NSCoder){
if let priceEncoded = self.Property1 {
aCoder.encodeObject(priceEncoded, forKey: "Property1")
}
}
}
知道我做错了什么吗?
Any idea what I'm doing wrong?
是的。不是很明显,但 "attempt to insert non-property list object" 几乎涵盖了它。您可以插入默认系统的对象种类仅限于 属性-列表类型:NSString
、NSDate
、NSNumber
、NSData
和集合 NSArray
和 NSDictionary
。您显然是在尝试插入其他类型的对象,因此出现了错误。
如果您想存储其他类型的对象,则需要以某种方式将其转换为受支持的类型之一。您走在正确的轨道上——通常的方法是使用 NSKeyedArchiver
序列化对象,它可以存储采用 NSCoding
协议的对象。这个想法是你创建一个键控归档器,用它来序列化有问题的对象,然后取回一个 NSData
的实例,然后你可以存储它。要取回对象,您可以执行相反的操作:使用 NSKeyedUnarchiver
将数据对象反序列化回原始对象。
看起来您希望 NSUserDefaults
为您序列化符合 NSCoding
的对象,但这并没有发生——您需要自己做。
周围有很多示例,但通常可以在 Archives and Serializations Programming Guide 中找到它。具体来说,查看示例代码的 "Creating and Extracting Archives" 部分。这是序列化的相关示例:
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:aPerson forKey:ASCPersonKey];
[archiver finishEncoding];
请记住,为了以这种方式序列化对象,该对象必须是采用 NSCoding
协议的 class 的实例。同一份文档解释了如何实现必要的 NSCoding
方法,而且在 SO 上肯定也有很多关于它的问题。
我有以下class。当我尝试像这样将它添加到 NSUserDefaults 时:
let testClass = TestClass()
testClass.Property1 = 22.3
NSUserDefaults.standardUserDefaults().setObject(testClass, forKey: "object1")
我收到一个错误:
'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object for key object1'
class TestClass: NSObject, NSCoding {
var Property1:Double?
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
if let priceCoded = aDecoder.decodeObjectForKey("Property1") as? Double {
self.Property1 = priceCoded
}
}
func encodeWithCoder(aCoder: NSCoder){
if let priceEncoded = self.Property1 {
aCoder.encodeObject(priceEncoded, forKey: "Property1")
}
}
}
知道我做错了什么吗?
Any idea what I'm doing wrong?
是的。不是很明显,但 "attempt to insert non-property list object" 几乎涵盖了它。您可以插入默认系统的对象种类仅限于 属性-列表类型:NSString
、NSDate
、NSNumber
、NSData
和集合 NSArray
和 NSDictionary
。您显然是在尝试插入其他类型的对象,因此出现了错误。
如果您想存储其他类型的对象,则需要以某种方式将其转换为受支持的类型之一。您走在正确的轨道上——通常的方法是使用 NSKeyedArchiver
序列化对象,它可以存储采用 NSCoding
协议的对象。这个想法是你创建一个键控归档器,用它来序列化有问题的对象,然后取回一个 NSData
的实例,然后你可以存储它。要取回对象,您可以执行相反的操作:使用 NSKeyedUnarchiver
将数据对象反序列化回原始对象。
看起来您希望 NSUserDefaults
为您序列化符合 NSCoding
的对象,但这并没有发生——您需要自己做。
周围有很多示例,但通常可以在 Archives and Serializations Programming Guide 中找到它。具体来说,查看示例代码的 "Creating and Extracting Archives" 部分。这是序列化的相关示例:
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:aPerson forKey:ASCPersonKey];
[archiver finishEncoding];
请记住,为了以这种方式序列化对象,该对象必须是采用 NSCoding
协议的 class 的实例。同一份文档解释了如何实现必要的 NSCoding
方法,而且在 SO 上肯定也有很多关于它的问题。