快速可变字典被视为不可变的 [英] Swift mutable dictionary being treated as immutable

查看:72
本文介绍了快速可变字典被视为不可变的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施应用内购买,并且正在跟踪用户通过NSUserDefaults购买了哪些购买.我有一个用于设置每次购买的值的函数,但是当它运行时,我收到一条错误消息,即使我用var而不是let声明了购买值的字典,但我正在对它进行变异NSMutableDictionary.有时它确实可以工作,但大多数情况下却不起作用.我收到一些有关使用let而不是var声明变量的警告,但是我忽略了它们,以使变量具有最大的可变性.为什么这不起作用?

I am trying to implement In App Purchases, and I am tracking which purchases a user has purchased via NSUserDefaults. I have a function that sets the values of each purchase, but when it runs, I get an error saying that I am mutating the dictionary of purchase values even though the dictionary is declared with a var instead of a let and is an NSMutableDictionary. Sometimes it does work, but most of the time it doesn't. I get a few warnings about declaring my variables with let instead of var, but I ignore them to give my variables maximum mutability. Why does this not work?

我得到的错误是:

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()
    }
}

推荐答案

这不是将不可变字典转换为可变字典的正确方法.

This is not the right way of converting an immutable dictionary into its mutable counterpart.

var已经确保从defaults.objectForKey(PURCHASES_KEY)返回的所有内容都将被复制为可变类型,因此您所需要的只是指定可变对象的类型,如果您确定所有对象,在我们的情况下可以安全地为Dictionary<String: AnyObject>键是String类型:

var already ensures that whatever is returned from defaults.objectForKey(PURCHASES_KEY) will be copied as a mutable type so all you need is specify the type of the mutable object which in our case can safely be Dictionary<String: AnyObject> if you are sure all keys are String type:

if var purchases = defaults.objectForKey(PURCHASES_KEY) as? Dictionary<String: AnyObject> {
  ...
  purchases[key] = value
}

请参见此SO问题有关集合类型中的可变性/不可变性的更多信息

Please see this SO question for more information about mutability/immutability in collection types.

这篇关于快速可变字典被视为不可变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆