为啥“预期解码数据但找到一个数组”我的代码中没有数组

Posted

技术标签:

【中文标题】为啥“预期解码数据但找到一个数组”我的代码中没有数组【英文标题】:Why "Expected to decode Data but found an array instead" I have no arrays in my code为什么“预期解码数据但找到一个数组”我的代码中没有数组 【发布时间】:2018-01-14 09:56:31 【问题描述】:

我有这个可编码的结构:

struct Foo: Codable 
    let rect: CGRect
    let image: UIImage

    init(rect: CGRect, image: UIImage) 
        self.rect = rect
        self.image = image
    

    func encode(to encoder: Encoder) throws 
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(rect, forKey: .rect)
        try container.encode(UIImagePNGRepresentation(image), forKey: .image)
    

    init(from decoder: Decoder) throws 
        let container = try decoder.container(keyedBy: CodingKeys.self)
        rect = try container.decode(CGRect.self, forKey: .rect)
        image = try UIImage(data: container.decode(Data.self, forKey: .image))!
    

    enum CodingKeys : CodingKey 
        case rect
        case image
    

现在我创建一个Foo 并尝试对其进行编码和解码:

let image = UIImage(named: "my_image")
let foo = Foo(rect: .zero, image: image!)
let encoder = PropertyListEncoder()
let data = try! encoder.encode(foo)
let decoder = PropertyListDecoder()
try! decoder.decode(Foo.self, from: data)

现在在decode 行,出现此错误:

Swift.DecodingError.typeMismatch(Foundation.Data, Swift.DecodingError.Context(codingPath: [__lldb_expr_244.Foo.CodingKeys.image], debugDescription: "预期解码数据,但找到了一个数组。",underlyingError: nil) )

显然解码器在尝试解码图像数据时发现了一个数组。为什么会这样?似乎Data 不知何故变成了一个数组。我很困惑,因为

Data() is Codable

评估为真,因此编码人员理论上应该能够对Data 进行编码/解码。为什么会变成数组?

编辑:我使用的是 Xcode 9.1

这里是my_image

【问题讨论】:

在一个新项目中尝试了这样的代码,我没有看到任何错误。 @AndreaMugnaini 你能在操场上跑吗? 它工作正常,当然我必须将图像添加到 Playground->Resources 这很奇怪......我会等着看看其他人是否可以重现这个。 一切似乎都对我有用,我的猜测是 Xcode9.1 中的东西(我正在测试 9.2)或图像的东西,你能附上你正在使用的实际图像在这里排除那部分? 【参考方案1】:

我确定这是一个错误,似乎问题出在编码过程中,当编码 UIImagePNGRepresentation 数据时,返回为 Optional 事情真的出错了,如果你更改 encode强制数据的方法如下:

container.encode(UIImagePNGRepresentation(image)!, forKey: .image)

代替:

container.encode(UIImagePNGRepresentation(image), forKey: .image)

这在 Xcode 9.1 和 9.2 中都可以使用,如果您将数据保留为可选,则编码将仅在 9.2 上有效并且在 9.1 中失败,由于某种原因,图像数据大小将在 9.1 上翻倍。

我很确定它是 swift.org 上的 this bug report

其中还提到它会导致内存使用量使数据大小增加一倍,这是我在本地设置中看到的。

因此,简单的解决方法是强制使用 UIImagePNGRepresentation(..) 数据或升级到修复此错误的 9.2。

希望这回答了你的问题,确实是非常有趣的发现!

【讨论】:

你找到它为什么找到一个数组了吗? 这可能有很多原因,我没有进入修复它的实际 PR,但我很确定如果你查看 code there 你会发现它不正确将值装箱,我没有深入研究代码的猜测是它要么默认为数组,要么数据由于某种原因在可选时被编码为数组,如果我在一周内有时间我会看看看看我是否可以查明问题发生的确切位置并更新我的答案:)

以上是关于为啥“预期解码数据但找到一个数组”我的代码中没有数组的主要内容,如果未能解决你的问题,请参考以下文章

为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]

为啥内核没有收到我的通用网络链接消息?

sqlserver连接池,为啥我的一个页面每刷新一次,数据库连接池就多一个链接数,同个网站下的别的页面

为啥我的图像的每行字节数大于其每像素字节数乘以其宽度?

为啥在我的 java 代码中没有调用通知

为啥我的改造代码没有在数据库中插入数据?