【问题标题】:Passing JSON objects around while mutating them在改变它们的同时传递 JSON 对象
【发布时间】:2016-06-20 14:45:06
【问题描述】:

如何构造一个可以被多个处理程序传递和变异的 JSON 对象,同时更新原始引用?

JSON 由 Swift 中的 Dictionary 和 Array 支持,它们都是 Struct 数据结构。根据定义,结构是按副本传递的。

这是我写的一个简单的单元测试

func testMutatingJson() {
    // Test
    var json: JSON = [
        "dict": [String: AnyObject]()
    ]

    json["dict"]["A"] = JSON(["key1": "value1"])
    json["dict"]["A"]["B"] = JSON(["key2": "value2"])

    XCTAssertEqual(json["dict"]["A"]["B"], JSON(["key2": "value2"]))

    let wrapper = Wrapper(json: json["dict"])
    wrapper.doSomething()

    // FAIL: This will fail since json["dict"]["A"]["B"] was copied into `Wrapper`
    XCTAssertEqual(json["dict"]["A"]["B"]["C"], JSON(["key3": "value3"]))
}

class Wrapper {

    var json: JSON

    init(json: JSON) {
        self.json = json["A"]["B"]
    }

    func doSomething() {
        self.json["C"] = JSON(["key3", "value3"])
    }

}

我需要修改原始 JSON 对象,因为它将在 doSomething() 之后再次处理。

我认为我最好的选择是编写我自己的由 NSMutableDictionary 和 NSMutableArray 支持的 JSON 类。还有其他选择吗?

【问题讨论】:

  • json != wrapper.json 您正在修改包装器中的那个,但随后您正在测试 testMutatingJson 中的那个。
  • 没错。重点是,Dictionary 和 Array 是结构类型。您不能通过引用传递。
  • 重点是测试原始JSON对象是否被修改(我知道不会,但我试图说明我的意图)。我想我唯一的选择是编写一个由 NSMutableDictionary 和 NSMutableArray 而不是 Swift 结构支持的 SwiftyJSON 等效项。
  • 是的,这正是我第二条评论的意思。由于您在问题中公开的原因,您不能使用 SwiftyJSON 进行这种参考行为。因此,您要么必须测试修改后的副本,要么更改策略并改用类。

标签: ios json swift swifty-json


【解决方案1】:

基本上,您已经有了解决方案 - 创建一个包装器对象,为封闭的 JSON 结构提供引用语义。您可能还可以重构代码,这样您就不会保留 JSON 对象的额外副本。

【讨论】:

  • 我将无法使用 JSON 结构,因为如果有任何孩子被传递和变异,我会遇到同样的问题。我正在尝试移植一个滥用 json 是按引用传递的事实的大型 JS 库。
猜你喜欢
  • 2021-07-22
  • 2013-10-30
  • 2012-11-27
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2013-12-09
  • 1970-01-01
相关资源
最近更新 更多