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

遵循Codable的Swift结构体属性使用@available(unavailable)报错如何解决

问题原因

@available(*, unavailable)标记表示该属性在所有平台均不可用,任何直接访问该属性的代码都会触发编译报错。
当结构体遵循Codable协议时,Swift编译器会自动生成编解码实现,自动生成的代码会直接访问所有存储属性,包括你标记为不可用的oldProperty,由此触发编译错误。
当结构体不遵循Codable时,只要你自己的业务代码没有访问oldProperty,就不会触发访问校验,因此可以正常编译。

解决方案

你需要手动实现Codable协议的编解码逻辑,完全绕过对oldProperty的访问即可解决问题,同时可以根据是否需要兼容旧数据字段选择实现方式:

方案1:不需要兼容旧的oldProperty字段

将不可用的属性改为计算属性,避免被自动合成的Codable逻辑识别为存储属性,同时手动声明编码键过滤旧属性即可:

struct SampleData: Codable {
    @available(*, unavailable, renamed: "newProperty")
    var oldProperty: String {
        fatalError("oldProperty 已废弃,请使用 newProperty")
    }
    let newProperty: String

    enum CodingKeys: String, CodingKey {
        case newProperty
    }
}

这种场景下编译器不会生成访问oldProperty的代码,编译可以正常通过。

方案2:需要兼容包含oldProperty字段的旧数据

手动实现完整的编解码逻辑,处理旧字段的兼容转换即可:

struct SampleData: Codable {
    @available(*, unavailable, renamed: "newProperty")
    var oldProperty: String {
        fatalError("oldProperty 已废弃,请使用 newProperty")
    }
    let newProperty: String

    enum CodingKeys: String, CodingKey {
        case newProperty
        case oldProperty
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // 优先读新字段, fallback 到旧字段
        self.newProperty = try container.decodeIfPresent(String.self, forKey: .newProperty) ?? 
            try container.decode(String.self, forKey: .oldProperty)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(newProperty, forKey: .newProperty)
    }
}

内容的提问来源于stack exchange,提问作者Kazunori Takaishi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 12:06:06