NSDictionary initWithContentsOfFile: desordena NSDecimalNumbers, ¿por qué?
-
10-07-2019 - |
Pregunta
En mi aplicación para iPhone, uso NSDecimalNumber
para almacenar algunos valores de tasa de cambio.
Extraigo los datos de la web la primera vez que se inicia la aplicación y luego nuevamente cuando se vuelven obsoletos, y los almaceno en un NSDictionary
; entonces uso writeToFile: atomically:
.
Cuando la aplicación se inicia por primera vez, mi método de conversión de tasas funciona bien. Sin embargo, cuando inicio la aplicación por segunda vez, y las tasas se cargan con - (NSDictionary *) initWithContentsOfFile:
el método de conversión deja de funcionar y obtengo resultados extraños.
Hice una depuración con puntos de interrupción en el método incriminado, y descubrí que los datos de las tasas se ven como NSCFNumber
, en lugar de como NSDecimalNumber
. Entonces parece que initWithContentsOfFile
no asigna la clase correcta a mis objetos. Para el registro, el valor real de estos objetos, como se muestra en el método description
, corresponde al valor de la tasa esperada.
También verifiqué el archivo plist generado por writeToFile: atomically:
, y vi que las tasas se almacenan como real
; Me pregunto si este es el tipo correcto.
¿Alguna idea de lo que está pasando?
Gracias de antemano,
Davide
Solución
Las listas de propiedades no distinguen entre números decimales y números de coma flotante. El elemento real
contiene un número de coma flotante. (De hecho, la serialización en sí misma puede ser simplemente NSNumber
enviando floatValue
a sí misma, sin saber que la instancia es realmente de una subclase. Eso significaría que la conversión a punto flotante ocurre cuando genera los datos de plist, no cuando los vuelve a leer)
Creo que tendrás que almacenarlo como una cadena. Con suerte, eso es sin pérdidas.
Otros consejos
Las listas solo funcionan con ciertos tipos de datos y NSNumber es uno de esos. Si desea el NSDecimalNumber, entonces tiene dos formas de hacerlo. El primero es seguir usando plists y luego convertir todos los NSNumbers a NSDecimalNumbers después de la carga. El segundo es cambiar a usar NSKeyedArchiver para almacenar datos. Esto requiere más código, pero significa que si guarda un NSDecimalNumber, obtendrá de nuevo un NSDecimalNumber.