UIImage经JSONEncoder/Decoder编解码后不等 一致性测试失败求助
问题根因定位
你的测试失败核心原因是UIImage转PNG再解码的过程丢失了原始实例的关键元信息,导致isEqual判断不相等,常见触发点如下:
- 你测试用的是
UIImage(systemName:)创建的系统符号图像:原始实例内置矢量描述、符号配置(字重、缩放等级)、符号标记位等元数据,转PNG后会被转为普通位图,丢失全部符号专属属性,两个实例本质类型存在差异,isEqual必然返回false - 通用UIImage的属性丢失:你当前的编解码实现仅存储了图像的位图数据,未保存UIImage的
scale、imageOrientation、renderingMode等核心属性,解码时默认生成scale为1的图像,和原始@2x/@3x的图像属性不一致,直接触发判等失败
排查思路
- 替换测试用的图像资源:不用系统符号图像,改用项目本地导入的普通PNG/JPG资源创建UIImage,重新跑测试判断是否是系统符号的专属问题
- 打印属性对比:分别输出原始UIImage和解码后UIImage的
scale、imageOrientation、renderingMode、isSymbolImage属性,确认是否存在差异 - 直接对比位图数据:将两个UIImage都调用
pngData(),直接对比Data是否相等,排除isEqual的非数据层面判断逻辑干扰
解决方案
方案1:修复通用UIImage编解码的属性丢失问题
修改UIImage的编解码逻辑,额外存储核心属性,示例实现如下:
编码时将UIImage封装为包含data、scale、orientation的结构体再编码,解码时用保存的属性重建UIImage:
// 辅助存储结构体 private struct ImageMeta: Codable { let data: Data let scale: CGFloat let orientation: Int } extension KeyedEncodingContainer { mutating func encode(_ value: UIImage, forKey key: Key) throws { guard let data = value.pngData() else { throw EncodingError.invalidValue( value, EncodingError.Context(codingPath: [key], debugDescription: "Failed convert UIImage to data") ) } // 封装核心属性 let imageMeta = ImageMeta(data: data, scale: value.scale, orientation: value.imageOrientation.rawValue) try encode(imageMeta, forKey: key) } } extension KeyedDecodingContainer { func decode(_ type: UIImage.Type, forKey key: Key) throws -> UIImage { let meta = try decode(ImageMeta.self, forKey: key) guard let image = UIImage(data: meta.data, scale: meta.scale) else { throw DecodingError.dataCorrupted( DecodingError.Context(codingPath: [key], debugDescription: "Failed load UIImage from decoded data") ) } return image.withOrientation(UIImage.Orientation(rawValue: meta.orientation) ?? .up) } }
方案2:适配系统符号图像的编解码
如果需要保留系统符号图像的特性,编码时额外判断是否是符号图像,存储符号名称和配置,解码时优先重建符号图像即可。
方案3:修改Equatable判等逻辑
如果不需要严格实例属性一致,只需要图像显示内容一致,修改ProfileImage的Equatable实现,直接对比PNG数据即可:
static func == (lhs: ProfileImage, rhs: ProfileImage) -> Bool { lhs.image.pngData() == rhs.image.pngData() }
内容的提问来源于stack exchange,提问作者PrayForTech
相关产品推荐
相关产品推荐

