我正在尝试对我的自定义类Car
执行简单的存档操作。我遵循了Apple文档并使其符合Codable
协议:
class Car: NSObject, Codable {
var name: String!
init(name:String) {
self.name = name
}
}
而且我想将其存档:
let car = Car(name: "Ferrari")
let data = NSKeyedArchiver.archivedData(withRootObject: car)
但是在第二行中,应用程序崩溃,并且出现以下错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_TtCC11Testing6MainVC3Car encodeWithCoder:]: unrecognized selector sent to instance 0x1c4035880' libc++abi.dylib: terminating with uncaught exception of type NSException
我已经搜索过SO,但是我只找到结构的解决方案,而我正在使用一个类。我该怎么办?
NSKeyedArchiver. archivedData(withRootObject:)
方法应用于符合NSCoding
NOT Codable/Encodable/Decodable
的对象。
如果您希望您的对象实现Codable
协议,则应使用JSONEncoder
和JSONDecoder
,如下所示:
let car = Car(name: "Ferrari")
if let encodedCar: Data = try? JSONEncoder().encode(car) {
let decodedCar = try? JSONDecoder().decode(Car.self, from: encodedCar)
}
如果您想使用NSKeyedArchiver
,则可以使用以下示例:
class Car: NSObject, NSCoding {
var name: String
init(name:String) {
self.name = name
}
required init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.value(forKey: "name") as? String else { return nil }
self.name = name
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
}
let data = NSKeyedArchiver.archivedData(withRootObject: car,
requiringSecureCoding: false)
您还应注意,iOS 12.0中不推荐使用archivedData(withRootObject:)
,而应使用+archivedDataWithRootObject:requiringSecureCoding:error:
。