NSDictionary initWithContentsOfFile: messes up NSDecimalNumbers, why?
-
10-07-2019 - |
Question
In my iPhone app I employ NSDecimalNumber
to store some some currency rate values.
I pull the data from the web the first time the app is launched and then again when they become obsolete, and I store them in a NSDictionary
; then I use writeToFile:atomically:
.
When the app is launched for the first time, my rate conversion method works allright. Yet, when I launch the app a second time, and the rates get loaded with -(NSDictionary*) initWithContentsOfFile:
the conversion methos stops working, and I get weird results.
I did some debug with breakpoints in the incriminated method, and I found out that the rates data are seen as NSCFNumber
, rather than as NSDecimalNumber
. So it appears that initWithContentsOfFile
doesn't assign the right class to my objects. For the record, the actual value of these objects, as shown in the description
method, corresponds to the expected rate value.
I also checked the plist file generated by writeToFile:atomically:
, and saw that the rates are stored as real
; I wonder whether this is the right type.
Any idea of whats going on?
Thanks in advance,
Davide
Solution
Property lists don't distinguish between decimal numbers and floating-point numbers. The real
element holds a floating-point number. (Indeed, the serialization itself may simply be NSNumber
sending floatValue
to itself, unaware that the instance is actually of a subclass. That would mean the conversion to floating-point happens when you generate the plist data, not when you read it back in.)
You'll have to store it as a string, I think. Hopefully, that's lossless.
OTHER TIPS
Plists only work with certain data types and NSNumber is one of those. If you want the NSDecimalNumber then you have two ways to go about it. The first is to keep using plists and then convert all the NSNumbers to NSDecimalNumbers after load. The second is to switch to using NSKeyedArchiver for storing data. This requires more code but means that if you save an NSDecimalNumber, you'll get an NSDecimalNumber back.