2015-09-09 4 views
5

Meine App speichert Einstellungen in einer Datei auf einem iOS-Gerät, indem Instanzen einer Klasse mit Eigenschaften archiviert werden. Die Klasse verwendet das NSCoding-Protokoll und daher kodiere ich diese Eigenschaften mit encodeWithCoder. Ich versuche dann, diese Dateien wieder in den Speicher mit einem Befehl wie tempInt = decoder.decodeIntegerForKey("profileFlags") as IntWie bekomme ich ein optionales von decodeIntegerForKey statt 0?

zu lesen. Das hat bisher gut funktioniert, aber jetzt muss ich in der Lage sein, zusätzliche Eigenschaften zu speichern und sie abzurufen. Im Wesentlichen wird die Struktur dieses archivierten Objekts geändert, aber Benutzer haben bereits Dateien mit der alten Struktur (die weniger Eigenschaften aufweist). Wenn der Benutzer eine Datei mit der neuen Struktur (zusätzliche Eigenschaften) hat, möchte ich sie lesen. Wenn nicht, möchte ich Code ausführen können, um das zu handhaben und Standardwerte zur Verfügung zu stellen.

Ich versuchte, einen nicht vorhandenen Schlüssel tempInt = decoder.decodeIntegerForKey("nonExistentKey") as Int zu verwenden, in der Erwartung, einen Nullwert zu erhalten, aber es gab eine Null zurück. Leider ist dies ein Ort, wo ich wirklich ein optionales brauche, weil 0 ein gültiger Wert ist.

Der nächste Hilfeartikel, den ich finden kann, ist Swift: decodeObjectForKey crashes if key doesn't exist, aber das scheint hier nicht zu gelten. Es scheint, als ob decodeObjectForKey einen optionalen Wert zurückgibt und decodeIntegerForKey einen Integer zurückgibt.

Irgendwelche Ideen, wie man das macht?

Antwort

7

können Sie überprüfen decoder.containsValueForKey("nonExistentKey") ob mit oder nicht gibt es einen tatsächlichen Wert vorhanden ist und nur dann, wenn es zu extrahieren ist es mit decodeIntegerForKey:

if decoder.containsValueForKey("nonExistentKey") { 
    let tempInt = decoder.decodeIntegerForKey("nonExistentKey") 
} 
+0

"Wenn die codierte Ganzzahl nicht in die Standard-Ganzzahl passt, löst die Methode eine NSRangeException aus." Leider ist das in Swift schwer zu handhaben. – jtbandes

0

@ luk2302 gab Ihnen die Antwort, aber ich wollte die Syntax leicht anpassen und erweitern es:

var tempInt: Int? 
let key = "profileFlags" 
let hasValue = decoder.containsValueForKey(key) 
tempInt = hasValue ? decoder.decodeIntegerForKey(key) : nil 

die letzte Anweisung wird als „Tertiär Operator“ verwendet wird, die die gleiche Wirkung hat wie:

if hasValue 
{ 
    tempInt = decoder.decodeIntegerForKey(key) 
} 
else 
{ 
    tempInt = nil 
} 

... aber alles in 1 Zeile. Es ist ein bisschen merkwürdig, bis man sich daran gewöhnt hat, aber es ist eine sehr prägnante Art, so etwas auszudrücken.

0

können Sie decodeObjectForKey verwenden, die Null anstelle von Null zurückgibt. Sie müssen nur wie folgt auf Int abstürzen:

decoder.decodeObjectForKey("profileFlags") as? Int