Codificación / decodificación CGFloat en 32 vs 64 bits
-
20-09-2019 - |
Pregunta
Me estoy convirtiendo en una aplicación para trabajar en 64 bits. Los documentos de Apple afirman que el tipo CGFloat
es un float
en 32 bits y un double
en 64 bits.
Si esto es así, ¿cómo manejar la codificación / decodificación del valor? Por ejemplo, si la creación de un NSNumber
de un CGFloat
, debería utilizar el método -numberWithFloat:
o -numberWithDouble:
de NSNumber? La misma pregunta se aplica a la NSCoder
NSKeyedArchiver
y -encodeFloat:forKey:
métodos y -encodeDouble:forKey:
.
¿Tengo que escribir una macro condicional para que -numberWithFloat:
se pidió a 32 bits y -numberWithDouble:
de 64 bits?
¿Qué ocurre si un usuario que ejecuta la versión de 64 bits de la aplicación guarda un archivo en el que estos valores se codifican como dobles y se abre el archivo / no almacenados en un sistema de 32 bits?
Todos los métodos en mi aplicación que utilizan CGFloats
es poco probable que alguna vez necesitan el nivel de precisión de un double
, por lo que debería ser incluso preocupando por esto?
Solución
¿Qué ocurre si un usuario que ejecuta la versión de 64 bits de la aplicación guarda un archivo en el que estos valores se codifican como dobles y se abre el archivo / no almacenados en un sistema de 32 bits?
No hay nada especial. El archivo contiene un double
, y es de suponer que va a enviar decodeDouble:forKey:
para recuperar el valor, de manera que obtendrá una double
. A continuación, puede echarlo a CGFloat
-que perderá precisión si estás en una máquina de 32 bits, pero hay que hacerlo fundido antes o después. (Incluso si se mantiene en el double
, usted todavía tiene que echar a CGFloat
cuando se pasa el valor de cuarzo / AppKit / UIKit.)
Considere la alternativa: Puede almacenar float
s en el archivo en una máquina de 64 bits, y luego cargar el archivo de nuevo en la misma máquina. Usted y cuarzo puede manejar toda la precisión del tipo double
de 64 bits, pero no lo tiene, debido a que tiró a la basura cuando escribió el archivo. Si el valor cambia en absoluto en el elenco, que el cambio es ahora permanente.
Así que mi recomendación es usar siempre el tipo double
con NSKeyedArchiver, a menos que sepa que son no va a utilizar cualquier cosa menos float
(es decir, la API objetivo sólo utiliza float
, nunca se double
). Esto no es cierto de cuarzo, por lo que para CGFloat
, utilice double
.