2016-05-13 14 views
3

Ich versuche, In-App-Käufe zu implementieren, und ich verfolge, welche Einkäufe ein Benutzer über NSUserDefaults gekauft hat. Ich habe eine Funktion, die die Werte jedes Kaufs setzt, aber wenn es ausgeführt wird, bekomme ich eine Fehlermeldung, dass ich das Wörterbuch der Kaufwerte mutieren, obwohl das Wörterbuch mit einer var anstelle einer let deklariert ist und eine NSMutableDictionary ist. Manchmal funktioniert es, aber die meiste Zeit nicht. Ich bekomme ein paar Warnungen über die Deklaration meiner Variablen mit let anstelle von var, aber ich ignoriere sie, um meine Variablen maximal änderbar zu machen. Warum funktioniert das nicht?Swift veränderbares Wörterbuch wird als unveränderlich behandelt

Der Fehler, den ich bekommen ist:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object' 

Code:

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 Da ich ein Schlüsselwertpaar einstelle, muss es vom Typ 'NSMutableDictionary' sein. Regulärer alter 'AnyObject' Typ lässt mich das nicht so weit ich weiß. – Aderis

+0

@ozgur Machen Sie Ihren Kommentar eine Antwort. Es scheint zu funktionieren, aber ich habe keine Ahnung warum. – Aderis

Antwort

3

Dies ist nicht der richtige Weg, um eine unveränderliche Wörterbuch in sein wandelbaren Gegenstück umzuwandeln.

var stellt sicher schon, dass alles, was von defaults.objectForKey(PURCHASES_KEY) zurückgegeben wird, wird als wandelbar Typ kopiert werden, um alles, was Sie brauchen, ist die Art des veränderlichen Objekts angeben, die in unserem Fall sicher Dictionary<String: AnyObject> sein können, wenn Sie sicher sind, alle Schlüssel sind String Typ:

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

Bitte sehen this SO question für weitere Informationen über Veränderlichkeit/Unveränderlichkeit in Kollektionstypen.