You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中结构体集合编码问题:NSKeyedUnarchiver弃用后的解决方案

结构体集合的归档/解归档替代方案(iOS)

你遇到的问题核心在于:NSKeyedUnarchiver的新API基于Objective-C的NSCoding协议,仅支持继承自NSObject的类类型,而Swift结构体属于值类型,无法遵循这类类协议。

最适配Swift值类型的解决方案是使用Swift原生的Codable协议,它完美支持结构体、枚举等值类型,编码解码逻辑更简洁,无需依赖Objective-C runtime。

步骤1:让结构体遵循Codable

给你的Cloud结构体添加Codable协议(如果结构体的所有属性都是默认支持Codable的类型,比如String、Int、Bool等,无需额外实现编码解码方法):

struct Cloud: Codable {
    // 你的结构体属性示例
    var identifier: String
    var storageSize: Int
    // 其他自定义属性...
}

步骤2:归档(编码)结构体集合到文件

替换原有的归档逻辑,用JSONEncoder或PropertyListEncoder将集合编码为Data后写入文件:

// 示例:要归档的Cloud集合
let cloudSet: Set<Cloud> = [
    Cloud(identifier: "cloud_01", storageSize: 512),
    Cloud(identifier: "cloud_02", storageSize: 1024)
]

// 获取文件存储路径(示例用Documents目录)
guard let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
    fatalError("无法获取Documents目录")
}
let archivePath = URL(fileURLWithPath: documentsDir).appendingPathComponent("clouds.archive").path

// 执行归档操作
do {
    // 可替换为PropertyListEncoder()生成更紧凑的二进制格式
    let encodedData = try JSONEncoder().encode(cloudSet)
    try encodedData.write(to: URL(fileURLWithPath: archivePath))
} catch {
    print("归档失败:\(error.localizedDescription)")
}

步骤3:解归档(解码)从文件读取集合

替换你原来的unarchiveObject(withFile:)代码,用JSONDecoder读取并解码:

// 读取相同的文件路径
guard let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
    fatalError("无法获取Documents目录")
}
let archivePath = URL(fileURLWithPath: documentsDir).appendingPathComponent("clouds.archive").path

// 执行解归档操作
do {
    let archivedData = try Data(contentsOf: URL(fileURLWithPath: archivePath))
    // 解码为Set<Cloud>类型
    let output = try JSONDecoder().decode(Set<Cloud>.self, from: archivedData)
    // 此处可使用解归档后的output集合
    print("解归档成功:\(output)")
} catch {
    print("解归档失败:\(error.localizedDescription)")
}

补充说明

  • 如果必须和旧的NSKeyedArchiver归档格式兼容,只能将Cloud改为继承自NSObject的类并实现NSCoding协议,但这会违背使用结构体的设计初衷。
  • Codable支持JSON和Plist两种编码格式:JSONEncoder生成的文件可读性更强,PropertyListEncoder生成的文件更紧凑,可根据需求选择。

内容的提问来源于stack exchange,提问作者Fabrizio Bartolomucci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:18:32