armv6 armv7 armv7s arm64引起编译包翻倍增大的问题,下边来说一下关于ios这个指令集

目前ios的指令集有以下几种:

  • armv6

    • iPhone
    • iPhone2
    • iPhone3G
    • 第一代和第二代iPod Touch
  • armv7
    • iPhone4
    • iPhone4S
  • armv7s
    • iPhone5
    • iPhone5C
  • arm64
    • iPhone5S

机器对指令集的支持是向下兼容的,因此armv7的指令集是可以运行在iphone5S的,只是效率没那么高而已~

在xcodeTARGETS里边Architectures:

Architecture : 指你想支持的指令集。

Valid architectures : 指即将编译的指令集。

Build Active Architecture Only : 只是否只编译当前适用的指令集。

================================================

现在是2014年初,其实4和4S的用户还是蛮多的,而iphone3之类的机器几乎没有了,所以我们的指令集最低必须基于armv7.

因此,Architecture的值选择:armv7 armv7arm64

PS:选arm64时需要最低支持5.1.1:

Convert Your App to a 64-Bit Binary After Updating It for iOS 7

Xcode 5.0.1 can build your app with both 32-bit and 64-bit binaries included. This combined binary requires a minimum deployment target of iOS 5.1.1 or later. The 64-bit binary runs only on 64-bit devices running iOS 7.0.3 and later. If you have an existing app, you should first update your app for iOS 7 and then port it to run on 64-bit processors. By updating it first for iOS 7, you can remove deprecated code paths and use modern practices. If you’re creating a new app, target iOS 7 and compile 32-bit and 64-bit versions of your app.

The architecture for 64-bit apps on iOS is almost identical to the architecture for OS X apps, making it easy to create a common code base that runs in both operating systems. Converting a Cocoa Touch app to 64-bit follows a similar transition process as the one for Cocoa apps on OS X. Pointers and some common C types change from 32 bits to 64 bits. Code that relies on the NSInteger and CGFloat types needs to be carefully examined.

Start by building the app for the 64-bit runtime, fixing any warnings that occur as well as searching your code for specific 64-bit issues. For example:

  • Make sure all function calls have a proper prototype.

  • Avoid truncating 64-bit values by accidentally assigning them to a 32-bit data type.

  • Ensure that calculations are performed correctly in the 64-bit version of your app.

  • Create data structures whose layouts are identical in the 32-bit and 64-bit versions of your app (such as when you write a data file to iCloud).

1,如果想自己的app在各个机器都能够最高效率的运行,则需要将Build Active Architecture Only改为NO,Valid architectures选择对应的指令集:armv7 armv7arm64。这个会为各个指令集编译对应的代码,因此最后的 ipa体积基本翻了3倍,Release版本必须NO。

2,如果想让app体积保持最小,则现阶段应该选择Valid architectures为armv7,这样Build Active Architecture Only选YES或NO就无所谓了

从iPhone 5S的A7 CPU开始到刚刚发布的iPhone 6(A8 CPU)都已经支持64-bit ARM 架构。关于64-bit的介绍详见维基百科。知乎上有很多关于苹果使用A7,A8芯片的讨论,可以参考 iPhone 6 的 Apple A8 芯片对比 Apple A7 提升明显吗?, iPhone 5s 配备的 A7 处理器是 64 位,意味着什么?

  • 1.Xcode 5.0.1开始支持编译32-bit和64-bit的Binary

  • 2.同时支持32-bit和64-bit,我们需要选择的minimum deployment target为 iOS 5.1.1

  • 3.64-bit的Binary必须运行在支持64-bit的CPU上,并且最小的OS版本要求是 7.0.3

关于Xcode “Build Setting”中的Architectures参数问题

  • 1.Architectures:你想支持的指令集。(支持指令集是通过编译生成对应的二进制数据包实现的,如果支持的指令集数目有多个,就会编译出包含多个指令集代码的数据包,造成最终编译的包很大。)

  • 2.Valid architectures:即将编译的指令集。(Valid architectures 和 Architecture两个集合的交集为最终编译生成的版本)

  • 3.Build Active Architecture Only:是否只编译当前设备适用的指令集(如果这个参数设为YES,使用iPhone 6调试,那么最终生成的一个支持ARM64指令集的Binary。一般在DEBUG模式下设为YES,RELEASE设为NO)

关于指令集如下参考:

ARMv8/ARM64: iPhone 6(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)

ARMv7s: iPhone 5, iPhone 5c, iPad 4

ARMv7: iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini

ARMv6: iPhone, iPhone 3G, iPod 1G/2G

对于支持64-bit,我们可以设置Architectures为 Standard architectures,在最新的Xcode 6上,它包括 armv7和arm64。

让App支持32-bit和64-bit基本步骤

1.确保Xcode版本号>=5.0.1

2.更新project settings, minimum deployment target >= 5.1.1

3.改变Architectures为 Standard architectures(include 64-bit)

4.运行测试代码,解决编译warnings and errors,对照本文档或者官方文档 64-Bit Transition Guide for Cocoa Touch对相应地方做出修改。(编译器不能告诉我们一切)

5.在真实的64-bit机器上测试。

6.使用Instruments查看内存使用问题。

64-bit主要的变化

64-bit运行时环境和32-bit运行时环境主要有以下两点的不同:

数据类型的改变

方法调用上的改变

数据类型的改变

整型数据类型的变化如下:

6af3d1aegw1elk0ftqdaxj20t00ky0wh.jpg

关于字节对齐的概念可以参考如下链接:C语言字节对齐

浮点型类型的改变如下:

6af3d1aegw1elk0g76x94j20h606uq3g.jpg

数据类型的改变可能会为我们的程序带来这些影响:

1.增加内存压力

2.64-bit到32-bit数据之间的相互转化

3.计算可能产生不同的结果

4.当把一个值从大的数据类型拷贝到小的数据类型,数据可能被截断。(NSInteger -> int)

方法调用上的改变

基于32-bit的CPU和基于64-bit上的CPU有不同数量的寄存器,在方法调用上有不同的协议。因此32-bit和64-bit在汇编层级上是不同的。如果我们在程序中不使用汇编编程,调用协议很少会遇到。

如何编写健壮的64-bit代码

根据上述改变,官方文档 64-Bit Transition Guide for Cocoa Touch给出如下7步:

1.不要将长整型long赋值给整型int (64-bit上会导致数据丢失)

2.不要将指针类型pointer赋值给整型int (64-bit导致地址数据丢失)

3.留意数值计算(掩码计算,无符号整数和有符号整数同时使用等)

4.留意对齐方法带来的变化

5.32-bit到64-bit之间数据转化(通过网络传递的用户数据,可能同时存在于32-bit和64-bit的环境下)

6.重写汇编代码

7.不要在可变参数方法和不可变参数方法之前进行强制转化

在LLVM编译器中,枚举类型也可以定义枚举的大小。我们在使用中,指派枚举值到一个变量时,应该使用适当的数据类型。

不要将指针类型pointer赋值给整型int

1
2
3
4
5
6
7
8
int a = 5;
int *c = &a;
/* 32-bit下正常,64-bit下错误。最新的Xcode6.0编译提示警告:'Cast to int* for smaller integer type int'*/
int *d = (int *)((int)c + 4); 
/* 正确, 指针可以直接增加*/
int *d = c + 1;

如果我们一定要把指针转化为整型,可以把上述代码改为:

1
2
/* 32-bit和64-bit都正常。*/
int *d = (int *)((uintptr_t)c + 4);

查看uintptr_t定义为 typedef unsigned long uintptr_t;

保持数据类型一致

方法使用时,入参,出参和赋值都需要注意保持数据类型一致。在iOS App中尤其要注意以下几个类型的正确使用:

  • long

  • NSInteger

  • CFIndex

  • size_t

在32-bit和64-bit下,fpos_t和off_t都是64 bits的数据大小,永远不要把它们指向int整型。

1
2
3
4
5
6
7
8
9
10
11
12
13
long PerformCalculation(void);
int c = PerformCalculation();  // 错误 64-bit上数据将被截取
long y = PerformCalculation();  // 正确
int PerformAnotherCalculation(int input);
long i = LONG_MAX;
int x = PerformCalculation(i);  // 错误
int ReturnMax()
{
     return  LONG_MAX;  // 错误
}

Cocoa中常见的数据类型转化问题

NSInteger : 在32-bit和64-bit下有分别的定义:

1
2
3
4
5
     #if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
         typedef long NSInteger;
     #else
         typedef int NSInteger;
     #endif

我们永远不应该假设NSInteger和int是一样大的,下面的例子在使用中就需要注意:

1.使用NSNumber对象转化时

2.使用NSCoder编解码的时候,如果在64-bit设备下对NSInteger编码,在32-bit设备下对NSInteger解码。解码时如果值的大小超过了32-bit,这个时候就会出现异常

3.Famework中使用NSInteger定义的一些常量

CGFloat: 和NSInteger一样有不同的定义

1
2
3
4
5
6
7
typedef CGFLOAT_TYPE CGFloat;
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
#else
# define CGFLOAT_TYPE float
#endif

下面给出错误示范:

1
2
3
4
5
CGFloat value = 200.0;
CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &value);  //64-bit下出现错误
CGFloat value = 200.0;
CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &value);  //正确

整型数值计算问题

关于C语言的符号位扩展可参考资料为:符号位扩展

我们直接来看例子:

1
2
3
4
5
6
7
8
9
     int a = -2;
     unsigned int b = 1;
     long c = a + b;
     long long d = c;
     printf( "%lld\n" , d);

问题:这段代码在32-bit下运行结果符合我们的预期,输出为 -1(0xffffffff)。在64-bit下运行结果为:4294967295 (0x00000000ffffffff)。

原因:一个有符号的值和一个同样精度的无符号的值相加结果是无符号的。这个无符号的结果被转换到更高精度的数值上时采用零扩展。

解决方案:把变量b换成长整型long

创建数据结构时使用合适的数据大小

C99提供了内置的数据类型保证了一致的数据大小,即使底层的硬件结构不同。在某些case下,我们知道数据是一个固定的大小或者一个特定的变量拥有一个有限的取值范围。这个时候,我们应该选择特定的类型以避免浪费内存。

类型如下:

32.jpg

永远不要使用malloc去为变量申请特定内存的大小,改为使用sizeof来获取变量或者结构体的大小。

另外我们还需要注意修改格式化字符串来同时支持32-bit和64-bit。

33.jpg

小心处理方法和方法指针

1
2
3
4
5
6
7
8
int fixedFunction(int a, int b);
int variadicFunction(int a, ...);
int main
{
     int value2 = fixedFunction(5,5);
     int value1 = variadicFunction(5,5);
}

上述两个方法中,在32-bit下使用相同的指令读取参数的数据,但是在64-bit上,是使用完全不同的协议来编译的。

如果在代码中传递方法指针,应该保证方法调用的协议是一致的。永远不要将一个可变参数的方法转化成固定参数的方法。

1
2
3
4
int MyFunction(int a, int b, ...);
int (*action)(int, int, int) = (int (*)(int, int, int)) MyFunction;
action(1,2,3);  // 错误示范

上述错误的写法,编译器是不会提示警告或者错误的,并且在模拟器中也不会暴露出问题来。在发布自己的App前,一定记得要使用真机去测试。

总结

在支持64-bit过程中,应该按照Apple文档中提供的7个步骤完整检查项目工程。如果工程中涉及到大量的C或者C++代码,在支持64-bit中要更加谨慎。

xcode armv7 armv7s arm64相关推荐

  1. xcode armv6 armv7 armv7s arm64

    眼下ios的指令集有下面几种: armv6 iPhone iPhone2 iPhone3G 第一代和第二代iPod Touch armv7 iPhone4 iPhone4S armv7s iPhone ...

  2. 关于iOS 编译器 armv7 armv7s arm64 i386 x86_64

    armv7 armv7s arm64 是ARM处理器的指令集 i386 x86_64 处理的指令集 对应的设备 arm64:iPhoneX | iphone8 plus|iPhone8| iPhone ...

  3. iOS armv7,armv7s, arm64

    目前ios的指令集有以下几种: armv6 iPhone iPhone2 iPhone3G 第一代和第二代iPod Touch armv7 iPhone4 iPhone4S armv7s iPhone ...

  4. 第26月第22天 iOS瘦身之armv7 armv7s arm64选用 iOS crash

    1.iOS瘦身之armv7 armv7s arm64选用 机器对指令集的支持是向下兼容的,因此armv7的指令集是可以运行在iphone5S以上的,只是效率没那么高而已~ 但是由于苹果要求必须支持ar ...

  5. iOS——armv7,armv7s,arm64详解

    这2天升级到xcode6,用ios8 SDK编译老项目,各种Undefined symbols for architecture xxx,精神差点崩溃了.不过最后还是解决了,本文简单总结一下 简单来说 ...

  6. iOS关于armv7,armv7s,arm64,i386,x86_64等问题

    iOS测试分为模拟器测试和真机测试,处理器分为32位处理器,和64位处理器, 模拟器32位处理器测试需要i386架构,(iphone5,iphone5s以下的模拟器) 模拟器64位处理器测试需要x86 ...

  7. iOS关于armv7,armv7s,arm64,i386,x86_64

    iOS测试分为模拟器测试和真机测试,处理器分为32位处理器,和64位处理器, 模拟器32位处理器测试需要i386架构,(iphone5,iphone5s以下的模拟器) 模拟器64位处理器测试需要x86 ...

  8. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv7s)

    问题: No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv ...

  9. ZBar 支持i386 armv6 armv7 armv7s x86_64 arm64

    ZBar 支持i386 armv6 armv7 armv7s x86_64 arm64 mp3转码静态库libmp3lame.a,成功加入arm64支持后, 顺便把之前记录的二维码静态库libzbar ...

最新文章

  1. deeplearning算法优化原理
  2. pandas创建复合索引dataframe仿真数据集实战(create a multiIndex dataframe)
  3. MyBatis之CRUD详解
  4. erhai系统使用_web
  5. oracle 安装 挂载磁盘组_ora-15077,ASM磁盘组不能挂载
  6. Tunnel Warfare(HDU1540+线段树+区间合并)
  7. echarts异步加载柱状图遇到的错误- Error: Component series. not exists. Load it first.
  8. 时间复杂度与O(1), O(n), O(logn), O(nlogn) 的区别
  9. ubuntu修改ls显示目录的颜色
  10. go的timer定时器实现
  11. agp模式_AGP的完整形式是什么?
  12. cassandra vs mongo (1)存储引擎
  13. VS2008使用技巧及快捷键大全
  14. phpwind测试之phpwind安装(二)
  15. 分享一例BIOS损坏修复案例
  16. asp.netcore 关于静态文件的访问权限控制(UseStaticFiles)
  17. 秀米数字编号实用知识点
  18. 800套绝美PPT模板免费下载
  19. d类数字功放芯片音质怎么样?
  20. iOS 格式化输出 位数不足补0

热门文章

  1. 基于VMware创建虚拟机以及安装虚拟机系统
  2. WIN7打开或关闭Windows功能后空白问题解决
  3. 【R】分类数据与数值型数据分组与绘图
  4. 如何解决javac不是内部或外部命令,也不是可运行程序的问题.
  5. 西门子1200四轴程序 新能源自动排列机,真实项目 4个V90 走PN 口控制4轴4个FB284控制
  6. cmd 调用oracle存储过程,asp.net中调用oracle存储过程的方法
  7. 高性能图片压缩 —— libjpeg-turbo 的编译与集成
  8. PS笔记 -- 混合模式
  9. vwap 公式_时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用...
  10. 市场调研报告-全球与中国商用燃气灶市场现状及未来发展趋势