rez*_*afi 5 encode dealloc nskeyedarchiver ios swift
当尝试在 iOS swift 中对我的自定义对象进行编码时,从 Xcode 8.3 获取此错误
无法识别的选择器发送到实例 0x60800166fe80 *** -[NSKeyedArchiver dealloc]:警告:NSKeyedArchiver 在没有调用 -finishEncoding 的情况下被释放。
我的代码是这样的:
导入 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)
}
}
Run Code Online (Sandbox Code Playgroud)
下面是一个如何使对象符合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")
}
}
Run Code Online (Sandbox Code Playgroud)
我还建议将您的setCustomObject方法更改为:
func setCustomObject(obj:NSCoding, key:String) {
let encodedObject : Data = NSKeyedArchiver.archivedData(withRootObject: obj)
UserDefaults.standard.set(encodedObject, forKey: key)
}
Run Code Online (Sandbox Code Playgroud)
这样编译器可以防止您传递NSKeyedArchiver不符合NSCoding协议的对象。
如果您不想在init方法中提供所有属性,可以使用默认值:
init(title : String? = nil, pageCount: Int? = nil){
self.title = title
self.pageCount = pageCount
}
Run Code Online (Sandbox Code Playgroud)
现在您可以只初始化对象而无需任何属性。像那样Book()