2016-11-24 3 views
2

Die decodeDouble on NSCoder gibt einen nicht optionalen Wert zurück, aber ich möchte identifizieren, ob ein Wert Null war, bevor es codiert wurde.NSCoder decodeDoppel des optionalen Werts

Das ist mein Szenario:

var optionalDouble: Double? = nil 

func encode(with aCoder: NSCoder) { 
    if let optionalDouble { 
     aCoder.encode(optionalDouble, forKey: "myOptionalDouble") 
    } 
} 

convenience required init?(coder aDecoder: NSCoder) { 
    optionalDouble = aDecoder.decodeDouble(forKey: "myOptionalDouble") 
    // here optionalDouble is never nil anymore 
} 

So Doppel kehrt Decodierung 0, falls der Wert nie eingestellt wurde, so ist es, wie ich vor der Codierung

war eigentlich 0 oder nil, ob ein Wert identifizieren kann nicht scheint

Gibt es eine Möglichkeit für mich zu überprüfen, ob ein Double war, bevor es codiert wurde?

+0

Sie zu machen kann in 'NSNumber?' konvertieren, um mit encodeObject zu speichern und 'decodeObject' anstelle von' decodeDouble' zu ​​verwenden –

+0

Müssen Sie in der Lage sein, zwischen dem Wert, der mit einem Wert von "nil" kodiert wird, und dem für den Schlüssel nicht vorhandenen Wert zu unterscheiden ? – Hamish

+0

Hat [diese Antwort] (http://stackoverflow.com/questions/39891190/how-doi-i-code-a-double-using-nscoder-nsobject-and-swift-3-for-ios/39895068#39895068) nützlich für Ihren Fall? –

Antwort

5

Die Lösung besteht darin, NSNumber anstelle von Double zu verwenden, wenn Sie codieren, und dann decodeObject zu verwenden, um (falls vorhanden) den doppelten Wert zurückzuerhalten. Zum Beispiel

class A: NSCoding { 
    var optionalDouble: Double? = nil 

    @objc func encodeWithCoder(aCoder: NSCoder) { 
     if let optionalDouble = optionalDouble { 
      aCoder.encodeObject(NSNumber(double: optionalDouble), forKey: "myOptionalDouble") 
     } 
    } 

    @objc required init?(coder aDecoder: NSCoder) { 
     if let decodedDoubleNumber = aDecoder.decodeObjectForKey("myOptionalDouble") as? NSNumber { 
      self.optionalDouble = decodedDoubleNumber.doubleValue 
     } else { 
      self.optionalDouble = nil 
     } 
    } 
} 

Mit Anregung von @Hamish, hier ist die Version für Swift 3. Beachten Sie, dass wir die Klasse NSObject, um erben müssen NSEncoding Arbeit (Got Unrecognized selector -replacementObjectForKeyedArchiver: crash when implementing NSCoding in Swift)

class A: NSObject, NSCoding { 
    var optionalDouble: Double? = nil 

    func encode(with aCoder: NSCoder) { 
     if let optionalDouble = optionalDouble { 
      aCoder.encode(optionalDouble, forKey: "myOptionalDouble") 
     } 
    } 

    override init() { 
     super.init() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     optionalDouble = aDecoder.decodeObject(forKey: "myOptionalDouble") as? Double 
    } 
} 
+4

Beachten Sie, dass Sie nicht explizit über 'NSNumber' gehen müssen - in Swift 3 einfach nur' aCoder.encode (optionalDouble, forKey: "myOptionalDouble") 'wird das' Double' mit 'NSNumber' überbrücken, wenn' optionalDouble' nicht-nil ist. Du kannst auch einfach 'as? Double 'im Dekodieren. – Hamish

+0

Danke für den Kommentar, es ist gut darüber zu wissen. –

Verwandte Themen