2016-05-13 2 views
3

私はApp App Purchasesを実装しようとしています。ユーザーがNSUserDefaultsで購入した購入を追跡しています。私は各購入の値を設定する関数を持っていますが、実行時にの代わりにvarと宣言され、NSMutableDictionaryであるにもかかわらず、購入値の辞書に突然変異が生じているというエラーが表示されます。時にはうまくいくこともありますが、ほとんどの場合はそうではありません。 varの代わりにletで変数を宣言することについていくつかの警告が出ますが、変数を最大限に変更するために無視します。なぜこれは機能しませんか?即時変更可能な辞書が不変として扱われています

私が手にエラーがある:

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

@ozgur私はキー値のペアを設定しているので、それは 'NSMutableDictionary'型でなければなりません。普通の 'AnyObject'型は、私が知る限り、それを私にさせません。 – Aderis

+0

@ozgurあなたのコメントを回答してください。それはうまくいったようですが、私は理由を知りません。 – Aderis

答えて

3

これは、その可変対応に不変の辞書を変換する正しい方法ではありません。

varはまだあなたが必要とするすべてはあなたがすべてのキーがStringタイプであることを確認している場合は、当社の場合には安全にDictionary<String: AnyObject>にすることができる可変オブジェクトの種類を指定しているdefaults.objectForKey(PURCHASES_KEY)から返されるものは何でも変更可能なタイプとしてコピーされることを保証します:

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

コレクションタイプの可変性/不変性の詳細については、this SO questionを参照してください。

関連する問題