最近項目里有一個功能被曝說在iphone5上失效,追查后的原因是一個id值在iphone5存儲到NSNumber時數據溢出導致的。開始時rd告訴我說是由于iphone5上的cpu架構是32位的,而從iphone5s開始cpu架構是64位的,代碼里用的int也是不同size導致。
雖然我沒寫過oc的代碼,但是我知道在c++里int的size是固定的4bytes,而long才是可變的。最終跟了一下代碼,原來代碼里用了NSInteger這個包裹類,而其定義為:
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
從定義可以看到,其定義是跟CPU總線位數相關的,而long得size是32位系統下為4bytes,64位系統下為8bytes。
從官方doc可以見到。
Table 1-1 Size and alignment of integer data types in OS X and iOS
Integer data type | ILP32 size | ILP32 alignment | LP64 size | LP64 alignment |
---|---|---|---|---|
char | 1 byte | 1 byte | 1 byte | 1 byte |
BOOL, bool | 1 byte | 1 byte | 1 byte | 1 byte |
short | 2 bytes | 2 bytes | 2 bytes | 2 bytes |
int | 4 bytes | 4 bytes | 4 bytes | 4 bytes |
long | 4 bytes | 4 bytes | 8 bytes | 8 bytes |
long long | 8 bytes | 4 bytes | 8 bytes | 8 bytes |