我有这个可编码的结构:
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:"预计会解码数据,但会找到一个数组。&#34 ;,underlyingError:nil))
显然解码器在尝试解码图像数据时发现了一个阵列。为什么会这样?似乎某种方式Data
变成了一个数组。我很困惑,因为
Data() is Codable
评估为true,因此编码器理论上应该能够对Data
进行解码。它为什么变成阵列?
编辑:我正在使用Xcode 9.1
以下是my_image
:
答案 0 :(得分:1)
我确定这是一个错误,似乎问题出在编码过程中,编码UIImagePNGRepresentation
数据时,Optional
数据返回encode
事情真的出错了,如果您更改container.encode(UIImagePNGRepresentation(image)!, forKey: .image)
方法以强制执行以下数据:
container.encode(UIImagePNGRepresentation(image), forKey: .image)
而不是:
UIImagePNGRepresentation(..)
在Xcode 9.1和9.2中都可以使用,如果保持数据可选,编码将仅在9.2上运行并且失败9.1,由于某种原因,图像数据大小将在9.1上加倍。
我很确定它在swift.org上的this bug report
其中还提到它会导致内存使用量增加一倍,这是我在本地设置中看到的。
所以简单的方法是强制pause
数据或升级到9.2修复此错误。
希望这能回答你的问题,确实非常有趣!