作者:很想爱到极限 | 来源:互联网 | 2022-12-09 18:46
如何解决《Unarchive数组与NSKeyedUnarchiverunarchivedObject(ofClass:from:)》经验,为你挑选了2个好方法。
自从升级到Swift 4.2以来,我发现许多NSKeyedUnarchiver和NSKeyedArchiver方法已被弃用,我们现在必须使用type方法static func unarchivedObject(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType?
来取消归档数据.
我成功地存档了我的定制类WidgetData的数组,这是一个NSObject子类:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData {
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
else { fatalError("Can't encode data") }
return data
}
当我尝试取消归档此数据时出现问题:
static func loadWidgetDataArray() -> [WidgetData]? {
if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA) {
if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data {
//THIS FUNCTION HAS NOW BEEN DEPRECATED:
//return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]
guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else {
fatalError("loadWidgetDataArray - Can't encode data")
}
guard let array = nsArray as? Array else {
fatalError("loadWidgetDataArray - Can't get Array")
}
return array
}
}
return nil
}
但这失败了,因为使用Array.self
而不是NSArray.self
禁止使用.我做错了什么,如何修复此问题以取消归档我的数组?
1> OOPer..:
您可以unarchiveTopLevelObjectWithData(_:)
用来取消归档所存档的数据archivedData(withRootObject:requiringSecureCoding:)
.(我相信这还没有被弃用.)
但在展示一些代码之前,你应该更好:
避免使用NSData
,Data
改为使用
避免使用try?
哪个配置错误信息对调试有用
删除所有不需要的演员阵容
试试这个:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
} catch {
fatalError("Can't encode data: \(error)")
}
}
static func loadWidgetDataArray() -> [WidgetData]? {
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else {
return nil
}
do {
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else {
fatalError("loadWidgetDataArray - Can't get Array")
}
return array
} catch {
fatalError("loadWidgetDataArray - Can't encode data: \(error)")
}
}
但是如果你正在制作一个新的应用程序,你最好考虑使用Codable
.
@GeoffH,它是原生的Swift序列化(归档)方式.(例如,它适用于`[WidgetData] .self`,你不需要关心`NSArray`或其他一些`NS`-事物.)最好从搜索"swift codable"开始,你可以找到很多好文章.
2> Maciej S..:
unarchiveTopLevelObjectWithData(_:)
也已弃用。因此,对于没有安全编码的非存档数据,您需要:
创建NSKeyedUnarchiver
与init(forReadingFrom: Data)
将requiresSecureCoding
创建的unarchiver 设置为false。
调用decodeObject(of: [AnyClass]?, forKey: String) -> Any?
以获取您的对象,只需使用适当的类并NSKeyedArchiveRootObjectKey
作为键即可。