setObject:forKey:发送到不可变对象的变异方法
setObject:forKey: mutating method sent to immutable object
我错过了什么...?
在我项目的其他地方有这样的代码:
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
错误:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
您不能只将 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
字典。所以你要么把改变后的内部字典写回外部字典,要么像我上面那样做。
我错过了什么...?
在我项目的其他地方有这样的代码:
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
错误:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
您不能只将 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
字典。所以你要么把改变后的内部字典写回外部字典,要么像我上面那样做。