[英]Cannot archive custom class object with NSKeyedArchiver
I am trying to perform a simple archive operation to my custom class Car
.我正在尝试对我的自定义类
Car
执行简单的存档操作。 I followed Apple documentation and made it conform to Codable
protocol:我遵循 Apple 文档并使其符合
Codable
协议:
class Car: NSObject, Codable {
var name: String!
init(name:String) {
self.name = name
}
}
And i want to archive it like:我想将它存档,如:
let car = Car(name: "Ferrari")
let data = NSKeyedArchiver.archivedData(withRootObject: car)
But in the second line the app crashes and i get the following error:但在第二行应用程序崩溃,我收到以下错误:
*** 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
I've searched SO but i only found solutions for structs, whereas i am using a class.我已经搜索过,但我只找到了结构的解决方案,而我正在使用一个类。 What can i do?
我能做什么?
The NSKeyedArchiver.archivedData(withRootObject:)
method should be used on objects that conform to NSCoding
NOT Codable/Encodable/Decodable
. NSKeyedArchiver.archivedData(withRootObject:)
方法应该用于符合NSCoding
NOT Codable/Encodable/Decodable
。
If you want your object to implement the Codable
protocol you can use the JSONEncoder
and JSONDecoder
like below to achieve the same thing:如果您希望您的对象实现
Codable
协议,您可以使用如下所示的JSONEncoder
和JSONDecoder
来实现相同的目的:
let car = Car(name: "Ferrari")
if let encodedCarData: Data = try? JSONEncoder().encode(car) {
let decodedCar = try? JSONDecoder().decode(Car.self, from: encodedCarData)
}
If you wish to use the NSKeyedArchiver
instead, you can use the example below:如果您希望使用
NSKeyedArchiver
,则可以使用以下示例:
class Car: NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool { return true }
var name: String
init(name: String) {
self.name = name
}
required init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.decodeObject(forKey: "name") as? String else { return nil }
self.name = name
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
}
let car = Car(name: "Ferrari")
if let encodedCarData =
try? NSKeyedArchiver.archivedData(withRootObject: car,
requiringSecureCoding: false) {
let decodedCar =
try NSKeyedUnarchiver.unarchivedObject(ofClass: Car.self,
from: encodedCarData)
}
You should also note, archivedData(withRootObject:)
was deprecated in iOS 12.0 and you should use +archivedDataWithRootObject:requiringSecureCoding:error:
instead.您还应该注意,
archivedData(withRootObject:)
在 iOS 12.0 中已弃用,您应该使用+archivedDataWithRootObject:requiringSecureCoding:error:
代替。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.