iOS 7: 如何爲iPhone 5s編譯64位應用

隨着 iPhone 5S的推出,你們開始關心 5S上所使用的 64位CPU A7。

除了關心A7的性能之外,你們還會關心一個問題,那就是使用A7的64位系統對應用有沒有什麼要求。特別是應用開發者,你們都比較關心咱們的應用如何遷移到64位的系統上來,以充分發揮A7的能力。其實這些問題均可以在蘋果的官方文檔《64-Bit transition Guide for Cocoa Touch》中找到答案。

爲了你們方便,我將《64-Bit transition Guide for Cocoa Touch》中的一些重點整理了一下,但願能夠爲你們節約一些詳細閱讀文檔的時間,若是我理解有不對的地方請你們指正。

首先,A7使用的是ARM V8架構,除了使用64位的地址總線和64位的寄存器之外,還增長了寄存器的數量,目前A7中的整數和浮點數寄存器是A6的兩倍。
這裏須要強調的是,寄存器的增長大大提升了程序的運行速度。將CPU由32位提升到64位,最主要的改變增大了尋址能力,能夠突破32位系統只能訪問3G內存的限制(感謝   wanglang3081 指出這裏的問題,32位系統在理論上能夠訪問4G內存,由於2的32次方約等於4 290 000 000,不少32位系統只能訪問3G左右的內存是由於有一大部分地址被分配給I/O系統了,因此整體可用內存就不足4G了。),可是,32位到64位的改變並不必定意味着程序運行速度的提升,甚至有些狀況下會由於64位系統中的數據佔用內存變大而致使程序運行速度變慢。而寄存器數量的增長,則直接提升了程序運行速度,固然,前提是你的應用須要從新爲64位系統編譯一遍,讓程序能夠充分使用全部的寄存器。

使用Xcode 5能夠很方便地將之前的應用編譯成64位程序,基本過程以下:
1. 使用Xcode 5 打開原有項目。
2. 將支持的設備改爲「iOS 7」。
3. 在「Build Setting」中將「Architectures」改爲「Standard Architectures (including 64-bit)」。
4. 運行測試程序,解決編譯過程出現的問題。

其中第4步是關鍵,具體會遇到什麼問題和原來程序的設計有關,包括使用數據類型的方式是否標準等,後面會繼續討論細節,其實《64-Bit transition Guide for Cocoa Touch》一書主要就是講這些細節。

在討論細節以前有一些較爲宏觀的內容你們能夠了解一下。

Xcode 5編譯的iOS 7程序包含了32位和64位兩套二進制代碼,在32位的iOS系統上會調用32位的二進制代碼,在64位系統上會調用64位的二進制代碼,以此來解決向後兼容的問題。

同時,考慮到不少32位的程序可能在沒有從新編譯的狀況下部署到64位系統上,64位的iOS系統中帶有兩套FrameWork,一套是32位的,一套是64位的。
當64位的iOS系統運行原來的32位程序時,系統會調用32位的FrameWork做爲底層支撐,當系統運行64位程序時,系統會調用64位的FrameWork做爲底層支撐。

也就是說,當一個iPhone 5S上同時運行32位程序和64位程序時,系統同時將32位和64位兩套FrameWork載入了內存中,因此消耗的內存也比較多。

若是一臺64位的iOS設備上運行的全部程序都是爲64位系統編譯過的,iOS系統將只載入64位的FrameWork,這將節省好多內存。因此,若是你們均可以快速將程序傳換成64位的,iOS將跑得更快。真的是「你們好纔是真的好」。


後面咱們來看看一些爲64位系統調整程序的技術細節。

32位的iOS系統和64位的iOS系統主要的差異有兩個,一個是 數據類型 的差異,一個是 過程調用 方法 的差異。

數據類型 上,主要的變化是指針類型(Pointer)和長整數類型(long)的長度變化和內存對齊方式的變化,同時也致使了更高級別數據類型的變化,如NSInteger的長度也有變化。

過程調用方法 上,由於ARM V8 和ARM V7具備不一樣數量的寄存器,具備不一樣的過程調用約定,因此32位系統和64位系統在彙編層級是不一樣的。

根據以上兩方面的變化,書中總結了如下要點,開發人員根據如下要點來檢查原來的32位代碼就差很少能夠將應用移植到64位系統上了:

1. 不要將長整型數據(long)賦予整型(int)
這種代碼在32位系統上沒有問題,由於在32位系統中long和int的長度是同樣的,不過在64位系統中就有可能出問題,由於64位系統中long比int長,將long值賦予int將致使數據丟失。

2. 不要將指針類型(Pointer)賦予整型(int)
爲了方便地址計算,有時程序員會將指針類型賦予整型,這種代碼在32位系統上沒有問題,由於在32位系統中Pointer和int的長度是同樣的,不過在64位系統中就會有問題,由於64位系統中Pointer比int長,將Pointer值賦予int將致使地址數據丟失,最終致使嚴重問題。

3. 留意那些和數位相關的數值計算
好比掩碼技術,若是使用一個long類型的掩碼,轉到64位系統後高位都是0,計算出來的結果可能不符合預期。還有無符號整數和有符號整數的混用等。

4. 留意對齊方式帶來的變化
若是在32位系統上定義一個結構包含兩個long類型,第二個long數值的偏移地址是4,能夠經過結構地址+4的方式獲取,可是在64位系統上就不行了,由於在64位系統中第二個long數值的偏移地址是8。

5. 充分考慮在32位應用和64位應用之間的數據交換
由於用戶會經過網絡交換數據,同時用戶保存的數據也可能經過備份等方式在32位系統和64位系統之間切換,因此應用在保存和發送流數據的時候必定要考慮充分。好比數據在32位系統中保存,在64位系統中可否正常打開,或者反過來,在64位系統中保存,在32位系統中打開是否正常。

6. 重寫全部彙編代碼
這點無需說明,若是你在代碼中嵌入了彙編代碼,你須要參考64位系統的指令集重寫彙編代碼。

7. 不要將可變參數的過程強制轉換爲定參過程,也不要將定參過程強制轉換爲可變參數的過程
這時由於32位系統和64位系統對於這兩種過程調用方式的處理方法不一樣。


按以上幾個重點去檢查程序就差很少了,固然,具體的細節還有不少,須要在實際工做中結合代碼和調試結果進行分析。
總之,建議具體負責應用遷移的開發者須要完整閱讀《64-Bit transition Guide for Cocoa Touch》。
相關文章
相關標籤/搜索