iOS 64位編程,ios64位編程
1.拒絕基礎資料型別 (Elementary Data Type)和隱式轉換1)基礎資料型別 (Elementary Data Type)
64位下,基本類型long從佔用4位元組變為佔用8位元組。要注意看一下程式中出現sizeof函數的地方,並注意盡量不要使用基礎資料型別 (Elementary Data Type),改用物件類型:
- int -> NSInteger
- unsigned -> NSUInteger
- float -> CGFloat
- 動畫時間 -> NSTimeInterval
- …
2)隱式轉換
NSArray *items = @[<a href="http://www.jobbole.com/members/1/" rel="nofollow">@1</a>, @2, @3];for (int i = -1; i < items.count; i++) { NSLog(@"%d", i);}
數組.count傳回值類型是NSUInteger,但這裡與i比較時,若i為-1,-1會被隱式轉換為很大的正整數,導致計算出錯。一定要注意和這個變數相關的所有操作(賦值、比較、轉換)
這裡將基礎資料型別 (Elementary Data Type)改為NSUInteger,初始值從0開始即可。此處只為舉例,遍曆還是用for-in或block更方便。
2.使用新版枚舉
typedef NS_ENUM(NSInteger, UIViewAnimationCurve) { UIViewAnimationCurveEaseInOut, UIViewAnimationCurveEaseIn, UIViewAnimationCurveEaseOut, UIViewAnimationCurveLinear};
3.替代Format字串
1) unsigned long類型轉為NSNumber:
(unsigned
long
)items.count 改為NSNumber
的@
文法糖: @(items.count).
2) int類型轉string:
NSInteger i = 10086;NSString *string = @(i).stringValue;
4. 64-bit下的BOOL
32-bit下,BOOL被定義為signed char
,@encode(BOOL)的結果是'c'
64-bit下,BOOL被定義為bool
,@encode(BOOL)結果是'B'
5.不直接取isa指標
編譯器已經預設禁用了這種使用,isa指標在32位下是Class的地址,但在64位下利用bits mask才能取出來真正的地址,若真需要,使用runtime的object_getClass
和object_setClass
方法。
6.解決第三方lib依賴和lipo命令
把target加上arm64
編譯,靜態庫(.a)或者framework,就需要重新找支援64-bit的包.
7.支援64-bit後程式包會變大嗎?
會。
Checklist
最後列一下官方文檔中的注意點:
- 不要將指標強轉成整數
- 程式各處使用統一的資料類型
- 對不同類型的整數做運算時一定要注意
- 需要定長變數時,使用如
int32_t, int64_t
這種定長類型
- 使用malloc時,不要寫死size
- 使用能同時適配兩個架構的格式化字串
- 注意函數和函數指標(類型轉換和可變參數)
- 不要直接存取Objective-C的指標(isa)
- 使用內建的同步原語(Primitives)
- 不要寫入程式碼虛存頁大小
- Go Position Independent
參考文章:
http://ios.jobbole.com/81561/