Swift 可变字典被视为不可变
Swift mutable dictionary being treated as immutable
我正在尝试实施 In App Purchases,我正在跟踪用户通过 NSUserDefaults
购买了哪些商品。我有一个函数可以设置每次购买的价值,但是当它运行时,我收到一条错误消息,指出我正在改变购买价值的字典,即使该字典是用 var
而不是 [=15 声明的=] 并且是一个 NSMutableDictionary
。有时它确实有效,但大多数时候无效。我收到一些关于使用 let
而不是 var
声明我的变量的警告,但我忽略它们以使我的变量具有最大的可变性。为什么这不起作用?
我得到的错误是:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
代码:
static func setPurchased(purchase:PurchaseID, value:Bool)
{
let defaults = NSUserDefaults.standardUserDefaults()
if (defaults.objectForKey(PURCHASES_KEY) == nil)
{
initializePurchases() // go set some initial values
}
if var purchases = (defaults.objectForKey(PURCHASES_KEY) as? NSMutableDictionary) // WARNING: should be declared with let because not mutated
{
print("setting purchase \(purchase.id()) to \(value)")
var key = purchase.id() // WARNING: should be declared with let because not mutated
purchases[key] = value // CRASH HERE
defaults.setObject(purchases, forKey:PURCHASES_KEY)
defaults.synchronize()
}
}
这不是将不可变字典转换为可变字典的正确方法。
var
已经确保从 defaults.objectForKey(PURCHASES_KEY)
返回的任何内容都将被复制为可变类型,因此您所需要的只是指定可变对象的类型,在我们的例子中可以安全地 Dictionary<String: AnyObject>
如果您确定所有键都是 String
类型:
if var purchases = defaults.objectForKey(PURCHASES_KEY) as? Dictionary<String: AnyObject> {
...
purchases[key] = value
}
有关集合类型中 mutability/immutability 的详细信息,请参阅 this SO question。
我正在尝试实施 In App Purchases,我正在跟踪用户通过 NSUserDefaults
购买了哪些商品。我有一个函数可以设置每次购买的价值,但是当它运行时,我收到一条错误消息,指出我正在改变购买价值的字典,即使该字典是用 var
而不是 [=15 声明的=] 并且是一个 NSMutableDictionary
。有时它确实有效,但大多数时候无效。我收到一些关于使用 let
而不是 var
声明我的变量的警告,但我忽略它们以使我的变量具有最大的可变性。为什么这不起作用?
我得到的错误是:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
代码:
static func setPurchased(purchase:PurchaseID, value:Bool)
{
let defaults = NSUserDefaults.standardUserDefaults()
if (defaults.objectForKey(PURCHASES_KEY) == nil)
{
initializePurchases() // go set some initial values
}
if var purchases = (defaults.objectForKey(PURCHASES_KEY) as? NSMutableDictionary) // WARNING: should be declared with let because not mutated
{
print("setting purchase \(purchase.id()) to \(value)")
var key = purchase.id() // WARNING: should be declared with let because not mutated
purchases[key] = value // CRASH HERE
defaults.setObject(purchases, forKey:PURCHASES_KEY)
defaults.synchronize()
}
}
这不是将不可变字典转换为可变字典的正确方法。
var
已经确保从 defaults.objectForKey(PURCHASES_KEY)
返回的任何内容都将被复制为可变类型,因此您所需要的只是指定可变对象的类型,在我们的例子中可以安全地 Dictionary<String: AnyObject>
如果您确定所有键都是 String
类型:
if var purchases = defaults.objectForKey(PURCHASES_KEY) as? Dictionary<String: AnyObject> {
...
purchases[key] = value
}
有关集合类型中 mutability/immutability 的详细信息,请参阅 this SO question。