我刚碰到这个,我想我找出了为什么会发生这种情况。如前所述,在方法调用中使用double
可以解决这个问题,这取决于您的代码是如何编译的,但这是有原因的。
This stack page说明两者的差异CGFloat的和浮动。有效地,CGFloat是围绕float或double的typedef“包装器”。无论它实际上是一个浮点数还是一个double,都取决于CGFloat被定义的头部,代码编译的目的。根据上述页面,您可以通过在代码编辑器中右键点击CGFloat
并转到“跳转到定义”来实际查看此标题(CGBase.h
)。你会看到这样的事情:
/* Definition of `CGFLOAT_TYPE', `CGFLOAT_IS_DOUBLE', `CGFLOAT_MIN', and
`CGFLOAT_MAX'. */
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif
/* Definition of the `CGFloat' type and `CGFLOAT_DEFINED'. */
typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1
通知行:
# define CGFLOAT_IS_DOUBLE 1
这个常量嵌套在这些标签定义CGFloat的是双重或浮动,根据#if defined(__LP64__) && __LP64__
这似乎取决于关于架构是否是64位。当你考虑这个问题时,根据你的机器的架构,提高精度是一个好主意。
一切顺利,直到你混合使用这个flag编译代码,与此标志关闭编译其它代码(如与其他代码的二进制库文件)。有效混合64位编译代码和32位编译代码。这会导致消息传递给期望浮动的方法。由于这一切都发生在字节级,没有错误抛出,字节被截断,取消了实际描述你的值的所有位,并留下没有任何内容的位,或0.
请注意,这当为OS X编译的代码和为iOS编译的代码混合使用时,可以很容易地发生,但是当编译模拟器和设备的二进制文件时,甚至可能会发生针对iOS编译的代码。
在32位下,'CGFloat'是一个'float',当类型未被明确知道时会导致问题。 (我知道我以前被这个咬过。) – Wevah 2010-06-10 22:42:57
同样的问题正在发生在我身上。如何解决这个问题? – Kamchatka 2010-07-19 02:58:27