Ios 更改NSMutableDictionary值时崩溃

Ios 更改NSMutableDictionary值时崩溃,ios,swift3,nsarray,nsdictionary,Ios,Swift3,Nsarray,Nsdictionary,我需要一些关于Swift 3.0中NSArray中NSMutableDictionary的帮助。 结构是一组字典 这是我的密码 class abc{ var myTempArr : NSArray! } // I need objC variables as I need to pass them as reference someMethod(){ myTempArr = [["title":"abc","id":"1"]] // creating a dicti

我需要一些关于Swift 3.0中NSArray中NSMutableDictionary的帮助。 结构是一组字典

这是我的密码

class abc{
    var myTempArr : NSArray! 
 }

  // I need objC variables as I need to pass them as reference

 someMethod(){
    myTempArr = [["title":"abc","id":"1"]] // creating a dictionary inside the array
   // I have changed the value like this also, but the crash remains
   // [["title":"abc","id":"1"] as! NSMutableDictionary]


 }


// This method is called in every key stroke in keyboard. Lets say we replace the "title", with the letter in the keyboard it is tapped

 func someotherMethod(){
      let firstDictionary = myTempArr[0] as! NSMutableDictionary
      // Its crashing here!!!!
      // Again i need nsmutabledictionary as i need to change the value
      // inside the dictionary so that the value inside the main array
      // that is myTempArr also changes. I need a pass by reference
      // method, hence i choosed NSMutableDictionary instead of swift dictionary

      firstDictionary["title"] = "New Title"
      // After this line, the original dictionary inside myTempArr
      // should change as well. But its crashing in the mentioned line

 }
我不想使用类实例,因为我知道它们也是通过引用传递的,但我需要应用谓词在数组中查找正确的字典,而不是通过索引进行搜索。这也是一个我无法理解的概念。请帮我弄清楚

坠机报告说:

无法强制转换类型为“Swift.\u SwiftDeferredNSDictionary”的值 (0x7facdb71e6c0)到“NSMutableDictionary”(0x102bfa350)

[编辑]

许多人都建议在变量中获取字典,更改变量,然后替换数组中的字典。我想避免这种方法,因为这与使用基于值的解决方案(Swift字典,其中传递值)是一样的。我想避免这种情况的原因是,我使用的原始DS有大量字典,而且字典的值经常发生变化。因此,我不认为使用替换字典的方法是合理的

我也知道,在斯威夫特,这是不好的,因为斯威夫特不是专为这一点。这种方法在目标C中工作得非常好,因为我们改变了变量(提示:变量指针),改变了它最初来自的变量。 如果有人能在Swift中推荐一种替代的或好的方法,那就太棒了

此外,为了简单起见,我使用了索引0。因为只有一本字典。但是在最初的DS中,正如我提到的,有很多字典,因此我使用谓词。这也是我为什么不使用类的实例(在swift中也是通过引用传递的)的原因,因为我不知道当我们通过谓词搜索类的实例时,它们的行为是否像字典

任何解决方案或替代方案都是非常受欢迎的。一如既往地感谢你们给我时间,因为我正努力思考如何采用新方法

试试这个

let firstDictionary = NSMutableDictionary(dictionary: myTempArr[0])

因为那本字典是不可变的。你不能这样施展它。 你可能想做这样的事情:

编辑:好的,这应该适合你,然后:

var tempArray: Array<Dictionary<String,String>>!
并按如下方式编辑词典:

func someotherMethod(){ 
     tempArray[0]["title"] = "New Title" 
}
编辑: 我不知道-听你的评论,也许这样的东西对你有用

关于获取正确词典的问题:

双重编辑:

if let dictionaryIndex = tempArray.index(where: {$0["title"] == "abc"}) {
        tempArray[dictionaryIndex]["title"] = "NOT ABC"
}

新兴城市。通过该==检查,您可以获得所需的确切字典,并更改确切的可变tempArray值。

您可以通过以下方式定义myTempArr:

func someMethod(){
    let nsmutabledict = NSMutableDictionary(dictionary: ["title":"abc","id":"1"])
    myTempArr = [nsmutabledict]

}

导致代码崩溃的原因是
NSArray
,需要更改为
NSMutableArray
,因为下标不支持
NSArray
的可变行为


检查下面的代码,并在代码生效后在代码内部进行更改:-

var myTempArr: NSMutableArray = [["title":"abc","id":"1"]] //Should be mutable for updating information
let dictionary = myTempArr[0] as? NSMutableDictionary ?? [:] //Getting here dictionay(Key value here)
dictionary["title"] = "New Title"  //Changing here value
myTempArr[0] = dictionary  //Finally updating on main array details

否则,可以尝试以下代码:-
代码输出:-

我认为字典可能是存储在数组中的错误数据结构。您已经指出,字典表示某种形式的表单字段。您可以创建一个对象来为这些字段建模,然后利用对象的易变性,同时仍然使用不可变数组

比如:

class Field {

    let id: Int
    let name: String
    var value: String

    init(id: Int, name: String, value: String = "") {
        self.id = id
        self.name = name
        self.value = value
    }

}

let firstNameField = Field(id:1, name:"FirstName")
let surnameField = Field(id:2, name:"Surname")

firstNameField.value = "Paul"

var fieldsArray = [firstNameField,surnameField]

firstNameField.value = "Peter"

print(fieldsArray[0].value)  // Prints Peter

if let field1 = fieldsArray.first(where:{ $0.id == 1} ) {    
    print(field1.value)  // Prints Peter
    field1.value = "John"
}

print(fieldsArray[0].value)  // Prints John

请注意,由于
Field
是一个类,因此我们能够使用引用语义,并且从不需要修改数组,因此在数组上没有复制修改操作

如果您想要一个
NSMutableDictionary
,那么您需要显式地创建一个,但是如果您有一个依赖于副作用的函数,那么您可能应该重新考虑您的设计。使用不变性可以提供更健壮的代码。是的,我同意,不变性是一条出路,但我需要处理一种由数据结构和字典数组支持的表单。现在,每次我通过该表单编辑字典中的任何内容时,我都需要更改字典的确切值。现在,这种设计方法不适用于Swift。但如果你能推荐其他的设计或型号,那就太好了。但到目前为止,我需要使用自定义类而不是字典和Swift
数组来解决这个问题。这也为您提供了引用语义。只要你能在Swift中避免
NSMutableArray/-Dictionary
,就去做吧!自定义类上的谓词是否会起作用,就像它们在swift中处理字典一样?您可以理解,我是swift的新手,所以请原谅我提出了这样的问题,当然会,但建议也使用本机函数,如
过滤器
。为什么要投反对票?我同意在swift中使用NS类并不是最好的选择,但这正是问题所在。我已经将其转换为NSMutableDictionary,并且仅在这一行中崩溃。而且,采用这种方法时,主阵列不会改变。始终替换字典不是一个选项,因为这是一个演示数组,它可能包含数千个字典,并且可能会发生变化,例如:每个键的笔划。请阅读我的评论,因为我写下了这种方法的错误之处。不能这样做,因为我需要用另一个变量捕捉确切的字典,因为我使用谓词来过滤精确的字典,而不是索引。因此,将您的代码应用于该逻辑,问题一直存在于您的问题中,您使用了索引0,因此我在我的问题中使用了索引0。您想更改索引0处词典的标题,我的代码就是这样做的。如果这不能解决你的问题,也许你应该在你的问题上加上你真正需要帮助的东西。在Playway中运行我的代码与您提出的问题完全一样。这不会更改主数组
myTempArr
,当我在此过程中更改
firstDictionary
中的任何内容时,您需要在
myTempArr
中使用
firstDictionary
替换旧字典。无法执行此操作,因为我使用的阵列是巨大的,任何
var array = [["title":"abc","id":"1"]] //Mutable Array
var dictionary = myTempArr[0] as? [String: String] ?? [:] //Getting here values
dictionary["title"] = "New Title" //Changing value
myTempArr[0] = dictionary // Updating Main array value
class Field {

    let id: Int
    let name: String
    var value: String

    init(id: Int, name: String, value: String = "") {
        self.id = id
        self.name = name
        self.value = value
    }

}

let firstNameField = Field(id:1, name:"FirstName")
let surnameField = Field(id:2, name:"Surname")

firstNameField.value = "Paul"

var fieldsArray = [firstNameField,surnameField]

firstNameField.value = "Peter"

print(fieldsArray[0].value)  // Prints Peter

if let field1 = fieldsArray.first(where:{ $0.id == 1} ) {    
    print(field1.value)  // Prints Peter
    field1.value = "John"
}

print(fieldsArray[0].value)  // Prints John