当前位置: 首页 > 面试题库 >

使用NSKeyedUnarchiver unarchivedObject(ofClass:from :)取消存档数组

颜畅
2023-03-14
问题内容

自从升级到Swift
4.2之后,我发现许多NSKeyedUnarchiver和NSKeyedArchiver方法已被弃用,我们现在必须使用type方法static func unarchivedObject<DecodedObjectType>(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<WidgetData> else {
                fatalError("loadWidgetDataArray - Can't get Array")
            }

            return array

        }

    }

    return nil

}

但这失败了,因为不允许使用Array.self代替NSArray.self。我在做什么错,我该如何解决才能取消存档阵列?


问题答案:

您可以unarchiveTopLevelObjectWithData(_:)用来取消归档由归档的数据archivedData(withRootObject:requiringSecureCoding:)。(我相信现在还不建议使用。)

但是在显示一些代码之前,您最好:

  • 避免使用NSDataData改用

  • 避免使用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



 类似资料:
  • 我得到了错误,而解压缩zip文件使用unArchive模块在我的anable playbook……它工作正常,有时我得到下面的错误 失败了!= 我使用下面的脚本代码来执行取消存档 有什么需要纠正的吗,我浏览了可调整的文档.....我希望我在正确的代码上,但仍然得到错误...请任何建议

  • 我的firestore数据库中有两个集合,第一个是所有文档的列表(区块列表),第二个是用户的集合。当用户在应用程序上为帖子添加书签时,只将此帖子的id发送到子收藏(收藏夹)。 那么,如何根据第一个集合的ID显示该子集合的文档呢。 我使用此代码访问子集合ID列表,但我想知道如何使用它从主集合(区块列表)中获取适合此ID的文档。

  • 根据http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html返回,如果被调用。 此方法返回后,对isDone()的后续调用将始终返回true。 但是,有可能任务正在运行并且设置为。那么,在调用之后应该返回什么?因为取消(这是错误的)而返回? 此外,尚不清楚方法是否返回。 P、 我正在实现一些简单的线程池,所以

  • 我正在尝试转换一个包含数组的JSON对象,并将数据卸载为单独的JSON。基本上,我需要为数组的每个元素创建一个对象,并复制所有外部数据。示例: 输入 预期产出 我尝试的规格: 我对 Jolt 很陌生,并尝试了几个不起作用的规格。我在取消嵌套部分时遇到问题。谢谢你的帮助。

  • Hangfire在发起一个取消任务请求或者终止任务时,为任务提供了取消令牌的支持,在前一种情况下,将自动放回队列的对头,允许Hangfire重新处理任务。 取消令牌通过 IJobCancellationToken 的接口暴露出来。当发起取消任务请求时,它通过 ThrowIfCancellationRequested 方法来抛出 OperationCanceledException : public

  • 在轻推,当一个群聊不再被使用时,群聊管理员可以选择将此群归档,以保持群聊列表的清爽。归档不会删除任何信息,并可以随时查看其历史消息,若想再次启用,也可以随时取消归档,即可恢复群聊被归档时的状态。 1.手机版 1)归档方法:群聊右上角图标-右上角菜单-归档群   2)取消归档方法:群聊右上角图标-右上角菜单-取消归档   2.电脑版 1)归档方法:群聊右上角图标-归档群   2)取消归档方法:群聊右