我剛碰到這個,我想我找出了爲什麼會發生這種情況。如前所述,在方法調用中使用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