setObject:forKey:发送到不可变对象的mutating方法

时间:2016-06-03 21:53:25

标签: ios swift nsmutabledictionary

我错过了什么......?

我项目的其他地方有这样的代码:

let allUsers = ["userName":["difficulty": 1, "highscore": 50],"userName2":["difficulty": 2, "highscore: 75]]          
defaults.setObject(allUsers, forKey: "allUsers")

我想更改该用户数组中一个用户的值:

var allUsers = defaults.objectForKey("allUsers") as! [String:NSMutableDictionary]

let changingUser = allUsers["userName"]! as NSMutableDictionary

这些都不会起作用:

changingUser.setObject(3, forKey: "difficulty")
changingUser["difficulty"] = 3

错误:

  

***由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:' - [__ NSCFDictionary setObject:forKey:]:发送到不可变对象的变异方法'

1 个答案:

答案 0 :(得分:1)

您无法将NSDictionary投射到NSMutableDictionary。你可以通过传入一个不可变的对应物来初始化一个,但不幸的是,这不是一个深度可变的结构。

但是,您可以将其转换为Swift词典并将其分配给var:

var allUsers = defaults.objectForKey("allUsers") as? [String: [String: Int]] ?? [:]
allUsers2["userName"]?["difficulty"] = 3

但请注意,Swift词典是值对象并具有值语义。也就是说,如果您按照以下步骤执行此操作:

var allUsers = defaults.objectForKey("allUsers") as? [String: [String: Int]] ?? [:]
changingUser = allUsers["userName"]
changingUser?["difficulty"] = 3 //mutates a copy

这不起作用,因为changingUser是一个副本,在写入它时,确实会改变它,它不会改变allUsers字典。因此,您必须将更改的内部字典写回外部字典,或者像我上面那样。