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

Swift中如何更新字典树形结构中子节点的数值?

问题分析与修复方案

问题原因

Swift中的字典是值类型,当调用child(key:)方法时,代码会把原字典的子节点拷贝成新的字典实例,再基于这个副本创建新的JSON对象。后续对副本的修改不会同步回原始字典,这就是修改c3后原字典值仍为5的核心原因。

修复方案

要实现类似Firebase的引用式节点修改,需让子节点的修改能同步回父节点的原始字典。可以通过让JSON类持有父节点引用和当前节点对应的key来实现:

class JSON {
    private var parent: JSON?
    private var currentKey: String?
    private var dict: [String: Any]
    
    // 根节点初始化
    init(_ dict: [String: Any]) {
        self.dict = dict
        self.parent = nil
        self.currentKey = nil
    }
    
    // 子节点初始化(私有方法,仅通过child方法调用)
    private init(parent: JSON, key: String) {
        self.parent = parent
        self.currentKey = key
        // 从父节点获取子字典,不存在则创建空字典
        self.dict = parent.dict[key] as? [String: Any] ?? [:]
    }
    
    func child(key: String) -> JSON {
        return JSON(parent: self, key: key)
    }
    
    func setValue(key: String, value: Any) {
        // 修改当前节点的字典
        dict[key] = value
        // 如果是子节点,将修改后的字典同步回父节点
        if let parent = parent, let key = currentKey {
            parent.dict[key] = dict
        }
    }
    
    func getInteger(key: String) -> Int {
        return dict[key] as! Int
    }
}

// 使用示例
var test: [String: Any] = ["c1": ["c2": ["c3": 5]]]
let json = JSON(test)

// 更新c3的值为27
json.child(key: "c1").child(key: "c2").setValue(key: "c3", value: 27)

print("JSON: \(json.child(key: "c1").child(key: "c2").getInteger(key: "c3"))")
// 输出:JSON: 27

修复原理

  • 子节点的JSON实例持有父节点的引用和当前节点对应的key,调用setValue时,不仅修改当前节点的字典,还会把更新后的字典同步到父节点的对应key位置。
  • 整个链式调用的节点通过父引用关联到根字典,确保所有修改都作用在原始字典结构上,实现类似Firebase的实时更新效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:47:07