【问题标题】:Swift 2 Dictionary<String, AnyObject> to Struct getter/setter throwing Cannot subscript value ... with an index of type 'String'Swift 2 Dictionary<String, AnyObject> to Struct getter/setter throwing Cannot subscript value ... with a index of type 'String'
【发布时间】:2016-05-27 05:21:32
【问题描述】:

我正在为使用结构的类属性编写 getter/setter。这最终从 JSON 解析并转换回 JSON,以便将数据存储在云中。

// struct:
public struct CompletedTask {
    var uuid: String!
    var amount: Float?
}

// array of completed tasks on the class:
public var completedTasks: [CompletedTask] {
    get {
        var getValue: [CompletedTask] = []
        if let _completedTasks = self["completedTasks"] as? [Dictionary<String, AnyObject>] {
            _completedTasks.forEach({
                getValue.append(CompletedTask(uuid: $0["uuid"], amount: nil))
            })
        }
        return getValue
    }
    set(value) {
        var setValue: [Dictionary<String, AnyObject>]
        value.forEach({
            if let amount = $0.amount where $0.amount != nil {
                setValue.append(["uuid": $0.uuid, "amount": amount])
            } else {
                setValue.append(["uuid": $0.uuid])
            }
        })
        self["completedTasks"] = setValue
    }
}

setter(我认为,虽然我无法测试)工作正常(无论如何它可以编译)。但是getter正在抛出:

Cannot subscript a value of type '[String : AnyObject]' with an index of type 'String'

发生了什么事?我认为这是一个简单的解决方法,但我尝试了几种不同的选项,但都不起作用。

【问题讨论】:

  • completedTasks 它是一个数组,所以你需要使用 Int 作为索引
  • 德拉特,见编辑。复制/粘贴失败。我正在做一个 forEach 并引用 $0;为什么那行不通?
  • self["completedTasks"] = setValueself 总会有一个数组
  • 真的不知道你在这里得到什么。即使我这样做this,我仍然有同样的问题。
  • 哦。我将其转换为字典而不是字典数组。 [] 与 [[]]。

标签: ios swift struct anyobject


【解决方案1】:

第一件事,

if let amount = $0.amount where $0.amount != nil

是多余的,因为没有where 子句的可选绑定保证满足if let 条件时数量不为零。

至于该消息,将AnyObject 更改为Any,因为StringStruct 而不是ClassAnyObject 仅适用于类。

更多关于AnyAnyObject的信息可以是found here

【讨论】:

    【解决方案2】:

    很抱歉这么说,但您的代码完全错误。

    值得注意的是,这段代码没有为我编译。我正在使用 Swift 2.0 和 xcode 7.2。此外,我想指出几点。

    1. 您不应该写入您的计算属性。而是查看存储的属性。 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID259

    2. 除非您要扩展字典,否则您不能为类的属性下标。要在闭包中访问类的属性,请使用 self.completedTask。

    3. 您不能简单地将您创建的类型的集合转换为字典集合。

    4. 我实际上没有看到任何转换为​​ JSON 的内容。我假设你在代码的其他地方做了这个。

    假设您想创建一个计算属性,将 CompletedTasks 列表保存为 Dictionary 并返回 CompletedTask 对象列表..

    public struct CompletedTask {
        var uuid: String!
        var amount: Float?
    }
    
    private var tasks : [[String: AnyObject?]] = []
    
    var completedTasks: [CompletedTask] {
        get {
            var _cT : [CompletedTask] = []
    
            tasks.forEach({
                _cT.append(CompletedTask(uuid: $0["uuid"] as! String, amount: $0["amount"] as? Float))
            })
    
            return _cT
        }
        set (value) {
            var _t : [[String: AnyObject?]] = []
    
            value.forEach({
                _t.append(["uuid": $0.uuid, "amount": $0.amount])
            })
    
            tasks = _t
        }
    }
    let task_1 = CompletedTask(uuid: "1", amount: nil)
    let task_2 = CompletedTask(uuid: "2", amount: nil)
    completedTasks = [task_1, task_2]
    print("Completed Tasks \(completedTasks)")
    

    【讨论】:

    • 公平地说,我发布的 sn-p 中有很多假设。该类继承自一个已经有下标的 super。最终的解决方案是我没有像您在回答中那样转换为 String/Float。
    【解决方案3】:

    错误仅仅是因为我没有在 getter 中转换类型:

    getValue.append(CompletedTask(uuid: $0["uuid"], amount: nil))
    

    应该是:

    getValue.append(CompletedTask(uuid: $0["uuid"] as? String, amount: nil))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 2022-12-01
      • 2016-08-16
      • 2022-12-27
      • 2022-12-02
      • 2022-11-20
      • 2022-12-02
      相关资源
      最近更新 更多