【问题标题】:NSKeyedArchiver will not archive simple dictionary with enum as valueNSKeyedArchiver 不会归档以枚举为值的简单字典
【发布时间】:2017-12-04 21:46:48
【问题描述】:

我正在尝试使用NSKeyedArchiver 来“归档”一个简单的字典。键是String 类型,值是enum

以下示例说明了我正在尝试做的事情:

import Foundation

enum Friend: String, Codable {
    case Ben, Max
}

let friends: [String: Any] = [ "bestFriend" : Friend.Ben ]
let archivedFriends = NSKeyedArchiver.archivedData(withRootObject: friends)

此代码可以复制到游乐场,结果将是以下错误:

错误:执行被中断,原因:信号 SIGABRT。

遗憾的是,我无法复制堆栈跟踪,所以我不得不创建一个屏幕截图:

为了测试enum 确实是问题,我将代码更改为以下内容:

import Foundation

let friends: [String: Any] = [ "bestFriend" : "Ben" ]
let archivedFriends = NSKeyedArchiver.archivedData(withRootObject: friends)

这行得通,所以问题是:

我在第一个代码示例中缺少什么让 NSKeyedArchiver 使用给定的字典?

【问题讨论】:

    标签: swift nskeyedarchiver


    【解决方案1】:

    使用原始值而不是直接使用枚举。

    let friends: [String: Any] = [ "bestFriend" : Friend.Ben.rawValue]
    let archivedFriends = NSKeyedArchiver.archivedData(withRootObject: friends)
    

    【讨论】:

    • 确实有效。非常感谢你。但说实话,这似乎有点奇怪。特别是,因为它使Codable 协议过时,我认为将协议添加到enum 的全部目的是使整个过程更加“用户友好”。 rawValue 只是枚举的字符串表示形式。
    • @Jens 使用NSKeyedArchiver 编码需要NSCoding,而不是Codable(除非您明确调用encodeEncodable)。 enum 不能符合 NSCoding,但它是 String rawValue 桥接到 NSString,确实如此。
    • @ItaiFerber 因为 Swift 4 Codable 也应该适用于枚举。我看到了多篇这样的博客文章:littlebitesofcocoa.com/318-codable-enums。只要我使用带有本身实现Codable 协议的类型的enum,它就应该可以工作。还是我看错了?
    • @Jens 是的,这就是制作enums Codable 的方法。但是,NSKeyedArchiverCodable 方面不起作用,而是在NSCoding 方面起作用,这完全是一个不同的 API。 Codable 不是 NSCoding,反之亦然。 NSKeyedArchiver 在 Swift 中有用于编码 Codable 事物的 API(encodeEncodabledecodeDecodable),但这不适用于 [String : Any] 内部的 enum 值;它必须被显式调用。
    • 非常感谢@ItaiFerber 澄清这一点!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2017-11-27
    • 2018-10-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多