32 位与 64 位上的 CGFloat 编码/解码
我正在将一个应用程序转换为在 64 位下运行。 Apple 文档指出,CGFloat
类型在 32 位上是 float
,在 64 位上是 double
。
如果是这样,您如何处理该值的编码/解码?例如,如果从 CGFloat
创建 NSNumber
,我应该使用 -numberWithFloat:
还是 -numberWithDouble:
NSNumber 的方法?同样的问题也适用于 NSCoder
和 NSKeyedArchiver
方法 -encodeFloat:forKey:
和 -encodeDouble:forKey:
。
我是否必须编写一个条件宏,以便在 32 位上调用 -numberWithFloat:
并在 64 位上调用 -numberWithDouble:
?
如果运行 64 位版本应用程序的用户保存一个文件,其中这些值被编码为双精度,并且该文件在 32 位系统上打开/取消存档,会发生什么情况?
我的应用程序中使用 CGFloats 的所有方法不太可能需要 double 的精度级别,所以我是否应该担心这一点?
I'm converting an app to work in 64-bit. The Apple docs state that the CGFloat
type is a float
on 32-bit and a double
on 64-bit.
If that is so, how do you handle encoding/decoding of the value? For instance, if creating an NSNumber
from a CGFloat
, should I use the -numberWithFloat:
or -numberWithDouble:
method of NSNumber? The same question applies to the NSCoder
and NSKeyedArchiver
methods -encodeFloat:forKey:
and -encodeDouble:forKey:
.
Do I have to write a conditional macro so that -numberWithFloat:
is called on 32-bit and -numberWithDouble:
on 64-bit?
What happens if a user running the 64-bit version of the app saves a file where these values are encoded as doubles and the file is opened/unarchived on a 32-bit system?
All the methods in my app that use CGFloats
are unlikely to ever need the precision level of a double
, so should I even be worrying about this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没什么特别的。该文件包含一个
double
,并且您可能正在发送decodeDouble:forKey:
来检索该值,因此您将获得一个double
。然后,您可以将其转换为 CGFloat,如果您使用的是 32 位计算机,这将失去精度,但您迟早必须执行该转换。 (即使您保留double
,当您将值传递给 Quartz/AppKit/UIKit 时,您仍然必须转换为CGFloat
。)考虑替代方案:将
float
存储在 64 位计算机上的文件中,然后将文件加载回同一计算机上。你和 Quartz 可以处理 64 位 double 类型的完整精度,但你没有,因为你在写出文件时把它扔掉了。如果值在演员阵容中发生了根本变化,那么该变化现在是永久性的。因此,我的建议是始终在 NSKeyedArchiver 中使用 double 类型,除非您知道您永远不会使用除 float 之外的任何类型(即,目标 API 仅使用
float
,从不使用double
)。 Quartz 则不然,因此对于CGFloat
,请使用double
。Nothing special. The file contains a
double
, and presumably you're sendingdecodeDouble:forKey:
to retrieve the value, so you'll get adouble
. You can then cast it toCGFloat
—which will lose precision if you're on a 32-bit machine, but you have to do that cast sooner or later. (Even if you hold onto thedouble
, you'll still have to cast toCGFloat
when you pass the value to Quartz/AppKit/UIKit.)Consider the alternative: You store
float
s in the file on a 64-bit machine, and then load the file back in on the same machine. You and Quartz can handle the full precision of the 64-bitdouble
type, but you don't have it, because you threw it away when you wrote out the file. If the value changed at all in the cast, that change is now permanent.So my recommendation is to always use the
double
type with NSKeyedArchiver, unless you know that you are never going to use anything butfloat
(i.e., the target API only usesfloat
, neverdouble
). This isn't true of Quartz, so forCGFloat
, usedouble
.