Codage / décodage CGFloat sur 32 vs 64 bits
-
20-09-2019 - |
Question
Je convertir une application pour travailler en 64 bits. L'état d'Apple documents que le type de CGFloat
est un float
sur 32 bits et un double
sur 64 bits.
Si c'est le cas, comment voulez-vous gérer le codage / décodage de la valeur? Par exemple, si la création d'un NSNumber
d'un CGFloat
, dois-je utiliser la méthode -numberWithFloat:
ou -numberWithDouble:
de NSNumber? La même question s'applique aux méthodes de NSCoder
et NSKeyedArchiver
-encodeFloat:forKey:
et -encodeDouble:forKey:
.
Dois-je écrire une macro conditionnelle de sorte que -numberWithFloat:
est appelé 32 bits et -numberWithDouble:
sur 64 bits?
Qu'est-ce qui se passe si un utilisateur exécutant la version 64 bits de l'application enregistre un fichier où ces valeurs sont codées en double et le fichier est ouvert / désarchivée sur un système 32 bits?
Toutes les méthodes dans mon application qui utilisent CGFloats
sont peu susceptibles d'avoir besoin du niveau de précision d'un double
, devrait donc cela? Je encore inquiétais
La solution
Qu'est-ce qui se passe si un utilisateur exécutant la version 64 bits de l'application enregistre un fichier où ces valeurs sont codées en double et le fichier est ouvert / désarchivée sur un système 32 bits?
Rien de spécial. Le fichier contient un double
, et sans doute que vous envoyez decodeDouble:forKey:
pour récupérer la valeur, de sorte que vous aurez un double
. Vous pouvez ensuite le jeter aux CGFloat
, qui va perdre la précision si vous êtes sur une machine 32 bits, mais vous devez faire CAST tôt ou tard. (Même si vous tenez sur le double
, vous aurez encore à jeter à CGFloat
lorsque vous passez la valeur à Quartz / AppKit / UIKit.)
Considérez l'alternative: Vous stockez float
s dans le fichier sur une machine 64 bits, puis chargez le fichier dos dans sur la même machine. Vous et Quartz pouvez gérer toute la précision du type de double
64 bits, mais vous ne l'avez pas, parce que vous l'a jeté loin quand vous avez écrit le fichier. Si la valeur a changé du tout dans le casting, le changement est désormais permanent.
Donc, ma recommandation est d'utiliser toujours le type de double
avec NSKeyedArchiver, sauf si vous savez que vous êtes jamais va utiliser quoi que ce soit, mais float
(à savoir, l'API cible utilise uniquement float
, jamais double
). Ce n'est pas le cas de quartz, donc pour CGFloat
, utilisez double
.