无法使用 NSKeyedArchiver 存档自定义 class 对象
Cannot archive custom class object with NSKeyedArchiver
我正在尝试对我的自定义 class 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 但我只找到了结构的解决方案,而我使用的是 class。我能做什么?
NSKeyedArchiver.archivedData(withRootObject:)
方法应该用于符合 NSCoding
而非 Codable/Encodable/Decodable
.
的对象
如果你想让你的对象实现 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)
}
如果您想改用 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)
}
您还应该注意,archivedData(withRootObject:)
在 iOS 12.0 中已弃用,您应该改用 +archivedDataWithRootObject:requiringSecureCoding:error:
。
我正在尝试对我的自定义 class 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 但我只找到了结构的解决方案,而我使用的是 class。我能做什么?
NSKeyedArchiver.archivedData(withRootObject:)
方法应该用于符合 NSCoding
而非 Codable/Encodable/Decodable
.
如果你想让你的对象实现 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)
}
如果您想改用 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)
}
您还应该注意,archivedData(withRootObject:)
在 iOS 12.0 中已弃用,您应该改用 +archivedDataWithRootObject:requiringSecureCoding:error:
。