IOS系統從07年出來,到如今也有6年了,每一年發佈一次到兩次新的設備,從iPhone1,iPhone2 ... iPhone4s再到最新的iPhone5。硬件在升級的過程當中CPU的架構也可能發生變化,如最先的armv6,armv7再帶最新的iPhone5因此用的armv7s。同時伴隨每一次硬件升級,系統都會作一次大版本的升級,目前最新的版本已經到了6.x了。html
每次系統升級的時候,總有一些用戶會由於各類緣由不肯或者不能升級到最新的系統。這就意味着,若是咱們的程序要讓儘量多的人使用,就得支持儘量多的硬件架構及系統版本。若是咱們寫的程序和硬件打交道比較少的話,要作的事也就是配置一下工程選項中的Architectures,在其中添加上咱們要支持的硬件架構就行了。然而每次系統的升級都會伴隨這不少新的API,Framework的引入,以及部分老的API的廢棄。也就說咱們要支持的系統版本越多,工做量也就越大,因此咱們一般會根據工做量和系統版本的分佈狀況作出取捨。如今AppStore上基本上的程序通常最多也就支持IOS 4.3的系統了吧,我作的上個項目PowerCam記得也是從4.0版本開始支持。ios
下面咱們分別從兩個方面討論一下:架構
1、支持多設備類型app
不一樣的設備CPU指令集多是不一樣的,這也就致使了其支持的框架可能不一樣。例如iPhone3G及以前版本的設備的CPU只支持armv6的指令集,致使了這些設備只支持OpenGL ES 1.1版本,全部iPad及iPhone3GS以後的全部設備都採用armv7及armv7s(iPhone5,iPad4採用)指令集,所以既能夠支持OpenGL ES 1.1和2.0。框架
2、支持多系統版本ide
Xcode在工程的編譯選項中,咱們能夠看到兩個選項:Base SDK和Deployment Target,第一個選項是用來設置咱們項目是基於哪一個版本的SDK開發,第二選項是用來設置咱們的項目最低能夠部署到哪個系統運行。函數
Xcode新建的工程中一般都會採用最用的SDK以及支持到最新的版本。由於咱們要既支持新的版本,同事兼顧的老的版本,爲了可以利用上新版本中新的特性,因此最好選擇最新的SDK,這一項一般不用改,維持原樣就好。若是要支持叫早的系統版本,則須要修改Deployment Target選項。以下圖所示,咱們設置項目須要最老的版本爲IOS 4.3。ui
到這兒就設置完了,Xcode會根據咱們的設置進行編譯打包。在這裏咱們討論一下Xcode是如何使用了最新版本的SDK,卻能夠支持到較老的系統版本呢?查閱文檔SDK Compatibility Guide發現,在程序打包的時候,Xcode只是將一些導出符號打到咱們的程序包中,具體到運行時會根據實際的設備的系統版本進行匹配。文檔中有一個圖能夠解釋Base SDK和Deployment Target之間是如何運做的,以下圖:spa
該圖是以Mac OS工程爲例的,不過原理是同樣的。意思是對於咱們支持部署的版本以前的全部API,咱們都是能夠無條件使用的(當前在新的版本中最好使用新的API),在咱們支持部署的版本和咱們開發所基於的SDK版本之間的API,可否使用取決於咱們的APP具體運行的系統版本。code
在系統版本升級的過程當中,一般會添加一些新的API和Framework,也會廢棄掉一些舊的效率不高的API。這些廢棄的API雖然不能立馬變得不可用,可是不保證在後面的版本中會繼續支持,因此爲了咱們的程序可以在新的系統中更可靠,高效的運行,咱們應該儘可能使用新的API。
不管是在新的系統版本中調用已經不支持了的API,仍是在舊的系統版本中調用新的系統版本中才引入的API都會致使咱們的程序Crush。所以咱們在調用那些咱們部署的版本之後添加的API或者Framework時須要進行判斷當前程序所運行的環境是否支持。
下面咱們從幾個方面討論:
1) 判斷一個類是否可用
在IOS 4.2之後咱們能夠經過class這個類方法來判斷一個類在當前運行時是否可用,代碼以下:
if ([UICollectionView class]) { // 6.0之後可使用 } else { // 以前的版本,須要使用可替代的技術實現 }
在Mac OS則須要使用NSClassFromString來判斷一個類是否可用。
2) 判斷一個方法是否可用
NSObject類有一個方法instancesRespondToSelector能夠用來判斷一個類的實例是否響應指定的方法,若是要判斷一個類是否響應一個類方法則可使用respondToSeletor方法。代碼以下:
if ([UIViewController instancesRespondToSelector:@selector(presentViewController:animated:completion:)]) { // 5.0之後支持 } else { // 不支持該方法 }
3) 判斷一個函數是否可用
咱們知道C語言中每一個函數名都表明着這個函數的地址,所以咱們能夠經過判斷該函數名字是否NULL來判斷支持該函數。
if (CGColorCreateCopyWithAlpha != NULL) { // 支持該函數 } else { // 不支持該函數 }
4) 判斷一個extern 變量或者Notification名是否可用
extern變量和Notification名其實都是一個變量,咱們只須要判斷它的地址是否NULL便可,代碼以下:
if (&MPMoviePlayerReadyForDisplayDidChangeNotification != NULL) { // 6.0之後存在該通知 } else { // 不存在該通知 }
該文檔中還講到若是你想針對不一樣的SDK版本進行條件編譯,能夠採用宏來實現,感興趣的同窗能夠本身看看。
至此,多版本多設備類型支持注意事項就介紹完了,但願對你們能有幫助。
參考文檔: SDK Compatibility Guide
注:轉自 http://www.cnblogs.com/smileEvday/archive/2013/04/10/SDKCompatility.html