@buoge
2017-08-09T14:14:37.000000Z
字数 4020
阅读 976
iOS
翻译看了一上午,发现前人已经总结好了:😁
如何让你的App 支持64位:
以防万一:本地打了个包:将你的iOS 工程转换为支持64位的版本.zip449.6kB
在补充一下:iOS armv7, armv7s, arm64区别与应用32位、64位配置
支持64位另外一个补充
32,64 关于int大小不一样,如有指针强转int需要修改
int *c = something passed in as an argument....
int *d = (int *)((int)c + 4); // Incorrect.
int *d = c + 1; // Correct!
If you must convert a pointer to an integer type, always use the uintptr_t type to avoid truncation
If the return type is a larger integer than the receiving variable, the value is truncated.
long PerformCalculation(void);
int x = PerformCalculation(); // incorrect
long y = PerformCalculation(); // correct!
2-3 Truncation of an input parameter
int PerformAnotherCalculation(int input);
long i = LONG_MAX;
int x = PerformCalculation(i);
2-4 Truncation when returning a value
int ReturnMax()
{
return LONG_MAX;
}
-Wshorten-64-to-32 让编译器检查32位于64位问题
if you modernized your project, the -Wshorten-64-to-32 compiler option was automatically enabled, so the compiler automatically warns you about many cases where a value is truncated. If you did not modernize your project, you should explicitly enable that compiler option. Optionally, you may want to include the -Wconversion option, which is more verbose, but finds more potential errors.
需要特殊关照的几种数据类型
In a Cocoa Touch app, look for the following integer types and make sure you are using them correctly:
And in both runtime environments, the fpos_t and off_t types are 64 bits in size, so never assign them to an int type.
In the LLVM compiler, enumerated types can define the size of the enumeration. This means that some enumerated types may also have a size that is larger than you expect. The solution, as in all the other cases, is to make no assumptions about a data type’s size. Instead, assign any enumerated values to a variable with the proper data type.
项目中枚举类型,一般数量都很少,32,64 不会超出范围
you should never make the assumption that an NSInteger type is the same size as an int type
NSCoder class. In particular, if you encode an NSInteger on a 64-bit device and later decode it on a 32-bit device, the decode method throws an exception if the value exceeds the range of a 32-bit integer. You may want to use an explicit integer type instead (see Use Explicit Integer Data Types).
NSInteger类型常量:NSNotFound本身就是NSIntegerMax
NSNotFound本身就是NSIntegerMax,NSIntegerMax则是LONG_MAX,也就是long类型的最大值.如果你通过断点观察,无效的NSInteger就是一个特别长的数.
static const NSInteger NSNotFound = NSIntegerMax;
define NSIntegerMax LONG_MAX
define LONG_MAX __LONG_MAX__
CGFloat,float,double 类型不可以混转,不然会出问题
float or a double. So use CGFloat consistently.
// Incorrect.
CGFloat value = 200.0;
CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &value);
// Correct!
CGFloat value = 200.0;
CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &value);
如果你在自己的代码中使用到了如上的方法转换,编译器可能不会给你警告或者错误,在模拟器上测试可能也不会出现问题,所以一定要在真机上进行测试。
由于 64位 编译器的支持,64位的 App 能够运行的更快一些,但是同样,占用的内存也会大一些,为了减少内存压力,你需要对你的 App 做一些内存方面的优化。
检查缓存
避免将64位的 long integer 赋值给32位的 integer
避免将64位的 指针 赋值给32位的 integer
避免因数学运算或其他操作造成 指针 和 long integer 的截断
修复因数据大小造成的字节对齐问题
确保数据在32位和64位下具有相同的内存结构
重写所有汇编代码使用64位的指令集
避免可变参数方法和不可变参数方法之间转换
if you modernized your project, the -Wshorten-64-to-32 compiler option was automatically enabled, so the compiler automatically warns you about many cases where a value is truncated. If you did not modernize your project, you should explicitly enable that compiler option. Optionally, you may want to include the -Wconversion option, which is more verbose, but finds more potential errors.