gpt4 book ai didi

swift - 解码子级时访问嵌套 Codable 结构中父结构的属性

转载 作者:行者123 更新时间:2023-12-03 09:25:56 25 4
gpt4 key购买 nike

在嵌套 Codable 中使用解码器时struct,有没有办法访问父结构的属性?

我能想到的唯一方法(尚未测试)是在父结构中也使用手动解码器,在 userInfo 中设置属性。字典,然后访问 userInfo在子结构中。但这会导致大量样板代码。我希望有一个更简单的解决方案。

struct Item: Decodable, Identifiable {
let id: String
let title: String
let images: Images

struct Images: Decodable {
struct Image: Decodable, Identifiable {
let id: String
let width: Int
let height: Int

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
width = try container.decode(Int.self, forKey: .width)
height = try container.decode(Int.self, forKey: .height)

// How do I get `parent.parent.id` (`Item#id`) here?
id = "\(parent.parent.id)\(width)\(height)"
}
}

let original: Image
let small: Image
// …
}
}

在上面的示例中,来自服务器的项目 ID 仅在 JSON 的顶级属性中定义,但我也需要在子项中使用它们,因此我也可以使它们 Identifiable .

最佳答案

我使用@New Dev 提到的 Itai Ferber 的建议进行了管理,方法如下:

  • 创建一个新的引用类型,其唯一目的是包含一个
    可以在父子之间传递的可变值。
  • 将该类型的实例分配给 JSONDecoder 的 userInfo 字典。
  • 在解码父对象时检索该实例,并将您有兴趣传递的 id 分配给它。
  • 在解码 child 的同时,从之前存储在 userInfo 中的实例中检索该 id。

  • 我已经修改了你上面的例子如下:
    struct Item: Decodable, Identifiable {

    enum CodingKeys: String, CodingKey {
    case id
    case title
    case images
    }

    let id: String
    let title: String
    let images: Images

    struct Images: Decodable {
    struct Image: Decodable, Identifiable {
    let id: String
    let width: Int
    let height: Int

    init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    width = try container.decode(Int.self, forKey: .width)
    height = try container.decode(Int.self, forKey: .height)

    if let referenceTypeUsedOnlyToContainAChangeableIdentifier = decoder.userInfo[.referenceTypeUsedOnlyToContainAChangeableIdentifier] as? ReferenceTypeUsedOnlyToContainAChangeableIdentifier {
    self.id = referenceTypeUsedOnlyToContainAChangeableIdentifier.changeableIdentifier
    } else {
    self.id = "something went wrong"
    }
    }
    }

    let original: Image
    let small: Image
    // …

    init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    id = try container.decode(String.self, forKey: .id)
    if let referenceTypeUsedOnlyToContainAChangeableIdentifier = decoder.userInfo[.referenceTypeUsedOnlyToContainAChangeableIdentifier] as? ReferenceTypeUsedOnlyToContainAChangeableIdentifier {
    referenceTypeUsedOnlyToContainAChangeableIdentifier.changeableIdentifier = id
    }
    }
    }
    }

    // Use this reference type to just store an id that's retrieved later.
    class ReferenceTypeUsedOnlyToContainAChangeableIdentifier {
    var changeableIdentifier: String?
    }

    // Convenience extension.
    extension CodingUserInfoKey {
    static let referenceTypeUsedOnlyToContainAChangeableIdentifier = CodingUserInfoKey(rawValue: "\(ReferenceTypeUsedOnlyToContainAChangeableIdentifier.self)")!
    }

    let decoder = JSONDecoder()
    // Assign the reference type here to be used later during the decoding process first to assign the id in `Item` and then
    // later to retrieve that value in `Images`
    decoder.userInfo[.referenceTypeUsedOnlyToContainAChangeableIdentifier] = ReferenceTypeUsedOnlyToContainAChangeableIdentifier()

    关于swift - 解码子级时访问嵌套 Codable 结构中父结构的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62242365/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com