下面是如何使對象符合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
協議。
如果你不想在init
方法,你可以使用默認值提供的所有特性:
init(title : String? = nil, pageCount: Int? = nil){
self.title = title
self.pageCount = pageCount
}
現在你可以初始化你的對象沒有任何屬性。這樣Book()
做你的'CustomObject'符合'NSCoding'協議嗎? – njuri
否@njuri,是否需要? –
是的,將在答案中描述。 – njuri