iOS指令集

1.ARM架构

ARM架构过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine),是一个32位精简指令集(RISC)处理器架构,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。

ARM和Intel处理器的第一个区别是,前者使用精简指令集(RISC),而后者使用复杂指令集(CISC)。

2.ARM处理器指令集

ARM指令集是指计算机ARM操作指令系统。

armv6、armv7、armv7s、arm64、arm64e都是arm处理器的指令集,所有指令集原则上都是向下兼容的。比如,你的设备是armv7s指令集,那么它也可以兼容运行比armv7s版本低的指令集:armv7、armv6。Xcode4.5起不再支持armv6。

苹果A7处理器支持两个不同的指令集:32位ARM指令集(armv6|armv7|armv7s)和64位ARM指令集(arm64)。
i386|x86_64 是Mac处理器的指令集。

i386通常被用来作为对Intel 32位微处理器的统称。X86-64可在同一时间内处理64位的整数运算,并兼容X86-32架构,x86_64是针对x86架构的64位处理器。当使用iOS模拟器的时候会遇到i386|x86_64,iOS模拟器没有运行arm指令集,编译运行的是x86指令集,所以,只有在iOS设备上,才会执行设备对应的arm指令集。

3.iOS设备支持的指令集

i386

  模拟器4s-5

x86-64

  模拟器5s及以上

armv6:

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

armv7:

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

armv7s:

   iPhone 5, iPhone 5c, iPad 4

arm64:

  iPhone X,iPhone 8(Plus),iPhone 7(Plus),iPhone 6(Plus),iPhone 6s(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)

arm64e:

  iPhone XS\XR\XS Max

4.Xcode->Build setting

1. Architectures

指定工程被编译成支持哪些指令集类型,而支持的指令集越多,就会编译出很多个指令集代码的数据包,对应生成二进制包就越大,也就是ipa包越大。

现在XCode->build setting 中Architectures的默认值是Standard architectures- $(ARCHS-STANDARD), $(ARCHS-STANDARD)的值如下图所示:

地址:https://pewpewthespells.com/blog/buildsettings.html#current_arch

2、Valid Architectures

该编译项指定可能支持的指令集,该列表和Architectures列表的交集,将是Xcode最终生成二进制包所支持的指令集。

比如,你的Valid Architectures设置的支持arm指令集版本有:armv7/armv7s/arm64,对应的Architectures设置的支持arm指令集版本有:arm64,这时Xcode只会生成一个arm64指令集的二进制包。

减少安装包中的指令集数据包可以减小打包ipa的大小。

3、Build Active Architecture Only:

指明是否只编译当前连接设备所支持的指令集。

默认Debug的时候设置为YES,Release的时候设置为NO。设置为YES是只编译当前的architecture版本,生成的包只包含当前连接设备的指令集代码。设置为NO,则生成的包包含所有的指令集代码(上面的Valid Architectures跟Architectures的交集)。因此为了调试速度更快,则Debug应该设置为YES。

特殊:设置此值为YES,如果连接的设备是arm64的( iPhone 5s,iPhone6(plus)等),则Valid Architecture 中必须包含arm64, 否则编译会报错(报错的内容在下面常见问题中)。

5.常见错误

1. 编译报错 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).

问题起因:active architecture(当前连接设备的指令集)为64位指令集,但是valid architecture只包含32位指令集
解决方法:valid architecture增加arm64 (常见的一些帖子的解决方案是把Build Active Architecture Only设置为NO,这是个简单粗暴的解决办法,在Debug过程中也会生成包含所有指令集的代码,更何况现在官方强制必须支持64位,故不建议采纳)

2. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=i386, VALID_ARCHS=x86_64).

问题起因:跟上个问题同理,只不过连接的设备指令集是32位指令集,但是valid architecture只包含64位指令集

解决办法:valid architecture增加armv7

3. 导入静态库后编译报错

问题起因:

  1. 可能是静态库中不包含这个类。
  2. 静态库工程可能没有链接到应用。
  3. 可能是因为静态库(.a)为真机版本,不包含模拟器版本(i386)。

解决办法:

  1. 查看静态库里面是否存在这个类。
  2. Build Phases中没有添加Link Binary With Libraries 中添加此静态库。
  3. 把调试目标换成真机 或者 导入一个模拟器版本跟真机版本合并的版本

同理如果导入的库是模拟器版本而用真机调试也会报错,所以导入一个通用的版本是目前来讲最好的办法。

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

当Build Active Architecture Only起作用时:连接的手机指令集匹配是由高到低(arm64 > armv7s > armv7)依次匹配的。

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

同样的,若Architectures列表为armv7,则会选取armv7作为目标指令集,若Valid Architectures列表中包含了armv7指令集,则能够成功生成二进制包,其支持的指令集只有armv7,若Valid Architectures列表中不包含armv7,则编译失败。

6.参考资料

 

posted @ 2019-05-20 15:35  LeeGof  阅读(854)  评论(0编辑  收藏  举报