詳細訊息位址為:
關於xcode 「build setting」中的architectures引數問題
關於指令集如下參考:
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。
1.確保xcode版本號》=5.0.1
2.更新project settings, minimum deployment target >= 5.1.1
3.改變architectures為 standard architectures(include 64-bit)
5.在真實的64-bit機器上測試。
6.使用instruments檢視記憶體使用問題。
64-bit主要的變化
64-bit執行時環境和32-bit執行時環境主要有以下兩點的不同:
資料型別的改變
方法呼叫上的改變
資料型別的改變
整型資料型別的變化如下
c語言位元組對齊
浮點型型別的改變如下:
資料型別的改變可能會為我們的程式帶來這些影響:
1.增加記憶體壓力
2.64-bit到32-bit資料之間的相互轉化
3.計算可能產生不同的結果
4.當把乙個值從大的資料型別拷貝到小的資料型別,資料可能被截斷。(nsinteger -> int)
方法呼叫上的改變
基於32-bit的cpu和基於64-bit上的cpu有不同數量的暫存器,在方法呼叫上有不同的協議。因此32-bit和64-bit在彙編層級上是不同的。如果我們在程式中不使用彙編程式設計,呼叫協議很少會遇到。
如何編寫健壯的64-bit**
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
保持資料型別一致
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
整型數值計算問題
關於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-bit和64-bit。
小心處理方法和方法指標
1
2
3
4
5
6
7
8
int fixedfunction(int a, int b);
int variadicfunction(int a, ...);
int main
上述兩個方法中,在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);
// 錯誤示範
總結
iOS工程支援arm64bit
joe 說明 以下是我在做64位公升級的各個步驟,裡面的例子僅僅是該步驟的一些例子而已,大家可以舉一反三,而 提示 裡是一些個人心得而已。1.配置專案檔案中相關的選項 1 確保需要支援arm64的各個targets裡的general的deployment target是5.1.1或以上 因為ios ...
iOS應用如何實現64位的支援
關於指令集如下參考 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,ipo...
iOS應用如何實現64位的支援
關於指令集如下參考 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,ipo...