Swift 数组添加了重复对象

Swift 数组添加了重复对象,swift,Swift,请查看下面的代码,当我将dictionary对象添加到NSMutableArry时,它会给我提供重复的对象。 tempArray是我要保存所有对象的数组。 字段是另一个数组,我将从中筛选一些对象 let tempArray = NSMutableArray() for i in 0..<fields.count { let dict = NSMutableDictionary() dict .setValue(fields[

请查看下面的代码,当我将dictionary对象添加到NSMutableArry时,它会给我提供重复的对象。 tempArray是我要保存所有对象的数组。 字段是另一个数组,我将从中筛选一些对象

let tempArray = NSMutableArray()
        for  i in 0..<fields.count {
            let dict = NSMutableDictionary()
            dict .setValue(fields[i].value(forKey: "interface_id"), forKey: "interface_id")
            dict .setValue(fields.fields[i].value(forKey: "type"), forKey: "type")
            dict .setValue(fields.fields[i].value(forKey: "icon"), forKey: "icon")

            if fields.fields[i].value(forKey: "type") == "Name"{
                dict .setValue("First Name", forKey: "label_name")
                dict .setValue("first_column", forKey: "column_name")
                tempArray.add(dict)

                dict .setValue("Last Name", forKey: "label_name")
                dict .setValue("last_column", forKey: "column_name")
                tempArray.add(dict)
            }
        }
但预期输出:

(
        {
         "interface_id"=1;
         "type"="Name";
         "icon"="G.JPG";
         "label_name"="First Name";
         "column_name"="first_column";
        },
  {
        "interface_id"=2;
        "type"="Name";
        "icon"="G.JPG",
        "label_name"="Last Name";
        "column_name"="last_column";
        }
  )

您的代码中有一个错误。 在相同的for循环迭代中,您可以执行以下操作:

       if fields.fields[i].value(forKey: "type") == "Name"{
            dict .setValue("First Name", forKey: "label_name")
            dict .setValue("first_column", forKey: "column_name")
            tempArray.add(dict)

            dict .setValue("Last Name", forKey: "label_name")
            dict .setValue("last_column", forKey: "column_name")
            tempArray.add(dict)
        }
这将首先将标签名称设置为first name,然后将其更正为Last name

因为在循环迭代方面没有任何改变,所以每个循环之间应该没有区别

编辑: 感谢@rmaddy的评论。 我完全同意:不要在Swift中使用NSMutableDictionary,除非你真的知道为什么需要它。(引用…-NSMutableDictionary和Swift中Dictionary的对象具有不同的内存管理规则)

此外,我会避免使用.setValue或.setObject。我宁愿使用

dict["column_name"] = "last_column"
我认为这更清楚

代码步骤(已解释):

(
        {
         "interface_id"=1;
         "type"="Name";
         "icon"="G.JPG";
         "label_name"="First Name";
         "column_name"="first_column";
        },
  {
        "interface_id"=2;
        "type"="Name";
        "icon"="G.JPG",
        "label_name"="Last Name";
        "column_name"="last_column";
        }
  )
  • 首先创建数组
  • 因此:

  • 通过迭代的第一个循环(i==0)
  • 你创造了词汇
  • 因此:

  • 您可以在其中添加三个值
  • 因此:

  • 然后检查“type”=“Name”
  • 因为你说的是真的
  • 因此:

  • 将此字典添加到数组中
  • 因此:

  • 你把字典改成
  • 因此:

    此时,更改dict指向的对象:这意味着在tempArray中,第一个位置有一个新值:

    // it is still 
    // ----->  tempArray = [dict]
    // but : dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "Last Name", "column_name": "last_column"}
    
    这就是为什么不在Swift中使用NSMutableDictionary和NSMutableArray的原因,如果您完全不知道为什么要使用它们

    建议的守则是:

    var tempArray: [Any] = []
        for  i in 0..<fields.count {
            let dict:[String:String] = [:]
            dict["interface_id"] = fields[i].value(forKey: "interface_id")
            dict["type"] = fields.fields[i].value(forKey: "type")
            dict["icon"] = fields.fields[i].value(forKey: "icon")
    
            if dict["type"] == "Name"{
                dict["label_name"] = "First Name"
                dict["column_name"] = "first_column"
                tempArray.append(dict)
    
    
                // In Swift Array we append object not reference, so this is working now.
                dict["label_name"] = "Last Name"
                dict["column_name"] = "last_column"
                tempArray.add(dict)
            }
        }
    
    var tempArray:[Any]=[]
    
    对于0中的i,那么我将如何做呢?请您提供一些逻辑,为什么您希望第二列与第一列不同,…使用
    setObject(\uuquorkey:)
    ,而不是
    setValue(\uquorkey:)
    。并使用
    对象(forKey:)
    ,而不是
    值(forKey:)
    。换句话说,除非您有明确的理由这样做,否则不要不必要地使用键值编码。最好不要在Swift中使用
    NSMutableDictionary
    。@inderpalingh,检查我的编辑。。。我想我明白你想做什么……这是斯威夫特。不要使用
    NS[Mutable]数组
    NS[Mutable]字典
    。使用Swift数组和Swift字典。如果您坚持使用
    NSMutableDictionary
    ,请使用
    setObject(\uuquo:forKey:)
    ,而不是
    setValue(\uquo:forKey:)
    。并使用
    对象(forKey:)
    ,而不是
    值(forKey:
    )。
    dict .setValue(fields[i].value(forKey: "interface_id"), forKey: "interface_id")
    dict .setValue(fields.fields[i].value(forKey: "type"), forKey: "type")
    dict .setValue(fields.fields[i].value(forKey: "icon"), forKey: "icon")
    //   ----->  dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG"}
    
    dict .setValue("First Name", forKey: "label_name")
    dict .setValue("first_column", forKey: "column_name")
    //   ----->  dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "First Name", "column_name": "first_column"}
    
    // ----->  tempArray = [dict] // Notice that I put here only pointer to the dict
    
    //   ----->  dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "Last Name", "column_name": "last_column"}
    
    // it is still 
    // ----->  tempArray = [dict]
    // but : dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "Last Name", "column_name": "last_column"}
    
    var tempArray: [Any] = []
        for  i in 0..<fields.count {
            let dict:[String:String] = [:]
            dict["interface_id"] = fields[i].value(forKey: "interface_id")
            dict["type"] = fields.fields[i].value(forKey: "type")
            dict["icon"] = fields.fields[i].value(forKey: "icon")
    
            if dict["type"] == "Name"{
                dict["label_name"] = "First Name"
                dict["column_name"] = "first_column"
                tempArray.append(dict)
    
    
                // In Swift Array we append object not reference, so this is working now.
                dict["label_name"] = "Last Name"
                dict["column_name"] = "last_column"
                tempArray.add(dict)
            }
        }