WrapperOfNSCoding失败,只有一个值 [英] WrapperOfNSCoding fails with single value

查看:94
本文介绍了WrapperOfNSCoding失败,只有一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自为UIColor实现可编码的问题

    struct WrapperOfNSCoding<Wrapped>: Codable where Wrapped: NSCoding {
        var wrapped: Wrapped

        init(_ wrapped: Wrapped) { self.wrapped = wrapped }

        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            let data = try container.decode(Data.self)
            guard let object = NSKeyedUnarchiver.unarchiveObject(with: data) else {
                throw DecodingError.dataCorruptedError(in: container, debugDescription: "failed to unarchive an object")
            }
            guard let wrapped = object as? Wrapped else {
                throw DecodingError.typeMismatch(Wrapped.self, DecodingError.Context(codingPath: container.codingPath, debugDescription: "unarchived object type was \(type(of: object))"))
            }
            self.wrapped = wrapped
        }

        func encode(to encoder: Encoder) throws {
            let data = NSKeyedArchiver.archivedData(withRootObject: wrapped)
            var container = try encoder.singleValueContainer()
            try container.encode(data)
        }
    }

    let colors = [NSColor.red, NSColor.brown]
    print(colors)
    let w = WrapperOfNSCoding(colors[0])
    let jsonData = try! JSONEncoder().encode(w) - fails
    let jsonData = try! JSONEncoder().encode(colors.map({ WrapperOfNSCoding($0) })) - succeeds

    print(jsonData)
    let colors2 = try! JSONDecoder().decode([WrapperOfNSCoding<NSColor>].self, from: jsonData).map({ $0.wrapped })
    print(colors2)

错误是在编码器中使用单个值时

The error is when a single value is used in the encoder

let w = WrapperOfNSCoding(colors[0])
let jsonData = try! JSONEncoder().encode(w)

错误是


致命错误:尝试!表达式意外引发错误:
Swift.EncodingError.invalidValue(WrapperOfNSCoding#1 ...

Fatal error: 'try!' expression unexpectedly raised an error: Swift.EncodingError.invalidValue(WrapperOfNSCoding #1...

成功

let w = WrapperOfNSCoding([colors[0]])
let jsonData = try! JSONEncoder().encode(w)

为什么是

推荐答案

JSONEncoder 在顶层需要有效的JSON上下文,可以是 [:] (字典)或 [] (数组),您可以在其中放置一个元素,例如此示例字符串

JSONEncoder need valid JSON context on the top level, which could be either [:] (Dictionary) or [] (Array), inside you can place an element like in this example string.

保存任何 NSCoding 对象,编译器将该对象视为字符串。对于 JSONEncoder()。encode(w),您正在尝试对 NSCoding进行编码对象,它充当 string 对象,而不是常规的 JSON 对象。

When you save any NSCoding object, the compiler treats that object as the string. In the case of JSONEncoder().encode(w), you are trying to encode an NSCoding object which acts as a string object instead of regular JSON object.

对于 JSONEncoder()。encode([w]),对象创建了一个数组,在您的情况下,每个元素都有一个字符串,该字符串为 NSCoding

In the case of JSONEncoder().encode([w]), the object has created an array and each element has a string which is NSCoding in your case.

以另一种方式 w 数据是一个字符串,而 [w] 是一个数组,每个索引都有一个字符串,因此 JSONEncoder 不会为您提供错误的 [w] ,并给您 w 的错误。

In another way w data is a string and [w] is an array with each index is having a string, therefore JSONEncoder is not giving you an error with [w] and giving you an error for w.

这篇关于WrapperOfNSCoding失败,只有一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆