提示:問題原因是iOS armv7, armv7s, arm64區別與應用32位、64位配置導致的(沒錯是這個導致的,相應的詳細資料可以在Google上搜或百度查看)
iOS armv7, armv7s, arm64區別與應用32位、64位配置歷程
1:先了解下64與32位的區別:數據類型的變化:在32位的年代,使用的是IPL32的規范,到了64位之后,改成了LP64規范。數據類型里面,NSInteger在32位時等同于int,在64位時等同于long,而這個數據結構使用很廣,很多不規范的時候會直接和int替換使用,在32位是毫無問題,但在64位時,這就是隱患了。CGFloat也有同樣的問題如果使用了偏移量來訪問struct的項,那么需要認真仔細的檢查,其余的還算好,當然如果你用了malloc,那么也請檢查一下分配的內存大小,建議是多使用sizeof來幫助計算。
示例圖:方法調用上的變化:在64位系統在運行時調用函數和32位系統是不同的。主要的區別在于傳遞具有可變參數個數的函數的參數時,我們來看下面的代碼(網上提供的):
?int fixedFunction(int a, int b);? int variadicFunction(int a, ...);?
int main? {??
?int value2 = fixedFunction(5,5);? int value1 = variadicFunction(5,5);?
?}
第一個函數是固定傳入2個參數,第二個函數是參數個數不定的,在使用中,也傳入了2個參數。在32位系統下,這兩個函數的參數傳遞是非常類似的,在64位系統下,這兩者就是截然不同了。
項目中使用的第三方庫肯定需要支持64位系統,否則還是白搭。
大家需要檢查自己使用的第三方的庫,看是否支持64位的版本。蘋果系統中(iOS7/iOS8-iOS9),32位的framework和64位的framework是共存的,所以如果所有的應用都是64位的話,系統就自動不加載32位的framework,這樣可以少占用資源,另外對運行的速度是有好處的,也就是說,你會感覺手機運行的快了一點。應用在兼容64位系統后,內存的占用肯定會變多一點,不過性能也有相應的提升。
增加應用對64位的支持:
一、配置前確認工作:如果你不能確定庫是否支持了arm64,可以在cmd模式下用file命令來檢查一下庫文件:是armv7,armv7s和arm64,i386,x86_64
這些都代表什么?
armv7|armv7s|arm64都是ARM處理器的指令集i386|x86_64 是Mac處理器的指令集了解Arm__Arm處理器,因為其低功耗和小尺寸而聞名,幾乎所有的手機處理器都基于arm,其在嵌入式系統中的應用非常廣泛,它的性能在同等功耗產品中也很出色。
Armv6、armv7、armv7s、arm64都是arm處理器的指令集,所有指令集原則上都是向下兼容的,如iPhone4S的CPU默認指令集為armv7指令集,但它同時也兼容armv6指令集,只是使用armv6指令集時無法充分發揮其性能,即無法使用armv7指令集中的新特性,同理,iPhone5的處理器標配armv7s指令集,同時也支持armv7指令集,只是無法進行相關的性能優化,從而導致程序的執行效率沒那么高。
這些指令集在哪些設備中有用到呢?arm64 ?armv7s armv7 iPhone6s iPhone5 iPhone4 iphone6s plus iPhone5C iPhone4S iphone6 iPad4(iPad with Retina Display) iPad iphone6 plus iPad2 iphone5s iPad3(The New iPad)iPad AiriPad miniiPad mini2 (iPad mini with Retina Display)iPod Touch 3GiPod Touch4>i386是針對intel通用微處理器32位處理器
>x86_64是針對x86架構的64位處理器
>模擬器32位處理器測試需要i386架構,
>模擬器64位處理器測試需要x86_64架構,
>真機32位處理器需要armv7,或者armv7s架構,
>真機64位處理器需要arm64架構。Xcode Build Setting中指令集相關選項釋義Architectures指定工程被編譯成可支持哪些指令集類型,而支持的指令集越多,就會編譯出包含多個指令集代碼的數據包,對應生成二進制包就越大,也就是ipa包會變大(Space-separated list of identifiers. Specifies the architectures (ABIs, processor models) to which the binary is targeted. When this build setting specifies more than one architecture, the generated binary may contain object code for each of the specified architectures. )。
Valid Architectures限制可能被支持的指令集的范圍,也就是Xcode編譯出來的二進制包類型最終從這些類型產生,而編譯出哪種指令集的包,
將由Architectures與Valid Architectures(因此這個不能為空)的交集來確定(Space-separated list of identifiers. Specifies the architectures for which the binary may be built. During the build, this list is intersected with the value of ARCHS build setting; the resulting list specifies the architectures the binary can run on. If the resulting architecture list is empty, the target generates no binary.)。
Build Active Architecture Only指定是否只對當前連接設備所支持的指令集編譯當其值設置為YES,這個屬性設置為yes,是為了debug的時候編譯速度更快,它只編譯當前的architecture版本,而設置為no時,會編譯所有的版本。 所以,一般debug的時候可以選擇設置為yes,release的時候要改為no,以適應不同設備。
二、工程配置,增加64位的支持> note:在Xcode6.1.1及以上 Valid Architectures 設置里, 默認為 Standard architectures(armv7,arm64),如果你想改的話,自己在other中更改。
使用 standard architectures (including 64-bit)(armv7,arm64) 參數,則打的包里面有32位、64位兩份代碼,在iPhone5s( iPhone5s的cpu是64位的 )下,會首選運行64位代碼包, 其余的iPhone( 其余iPhone都是32位的,iPhone5c也是32位 ),只能運行32位包,但是包含兩種架構的代碼包,只有運行在ios6,ios7系統上。 這也就是說,這種打包方式,對手機幾乎沒要求,但是對系統有要求,即ios6以上。使用 standard architectures (armv7,armv7s) 參數, 則打的包里只有32位代碼, iPhone5s的cpu是64位,但是可以兼容32位代碼,即可以運行32位代碼。但是這會降低iPhone5s的性能。 其余的iPhone對32位代碼包更沒問題, 而32位代碼包,對系統也幾乎也沒什么限制。要發揮iPhone5s及以上的64位機型性能,就要包含64位包,那么系統最低要求為ios6。 如果要兼容ios5以及更低的系統,只能打32位的包,系統都能通用,但是會喪失iPhone5s的性能。
舉例:
>比如 Valid Architectures設置的支持arm指令集版本有:armv7/armv7s/arm64,
對應的Architectures設置的支持arm指令集版本有:armv7s,
這時Xcode只會生成一個armv7s指令集的二進制包。
其他原理類似就在這里不在一一細說了。
當然以上都是一些工程配置問題(工程中的代碼是否使用32位的,一些庫是不是用的32位的都會有問題)會出現提示“xxx可能使iPhone變慢”