当尝试在 iOS swift 中编码我的自定义对象时,从 Xcode 8.3 收到此错误
unrecognized selector sent to instance 0x60800166fe80 *** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.
我的代码是这样的:
导入 UIKit 导入基金会
class Place: NSObject {
func setCustomObject(CustomObject obj:Any,Key key:String) {
let encodedObject : Data = NSKeyedArchiver.archivedData(withRootObject: obj)
UserDefaults.standard.set(encodedObject, forKey: key)
}
}
最佳答案
下面是一个如何使对象符合 NSCoding
的示例。基本上你需要提供两种方法的实现 - required convenience init?(coder decoder: NSCoder)
和 encode(with aCoder: NSCoder)
class Book: NSObject, NSCoding {
var title: String?
var pageCount: Int?
// Memberwise initializer
init(title: String,pageCount: Int) {
self.title = title
self.pageCount = pageCount
}
// MARK: NSCoding
// Here you will try to initialize an object from archve using keys you did set in `encode` method.
required convenience init?(coder decoder: NSCoder) {
guard let title = decoder.decodeObject(forKey: "title") as? String else { return nil }
self.init(title: title, pageCount: decoder.decodeInteger(forKey: "pageCount"))
}
// Here you need to set properties to specific keys in archive
func encode(with aCoder: NSCoder) {
aCoder.encode(self.title, forKey: "title")
aCoder.encodeCInt(Int32(self.pageCount), forKey: "pageCount")
}
}
此外,我建议将您的 setCustomObject
方法更改为:
func setCustomObject(obj:NSCoding, key:String) {
let encodedObject : Data = NSKeyedArchiver.archivedData(withRootObject: obj)
UserDefaults.standard.set(encodedObject, forKey: key)
}
这样编译器会阻止您向 NSKeyedArchiver
传递一个不符合 NSCoding
协议(protocol)的对象。
如果您不想在 init
方法中提供所有属性,您可以使用默认值:
init(title : String? = nil, pageCount: Int? = nil){
self.title = title
self.pageCount = pageCount
}
现在你可以在没有任何属性的情况下初始化你的对象。就像那个Book()
关于ios - NSKeyedArchiver.archivedData 在 Swift 3 iOS 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43446028/