下面舉個(gè)簡(jiǎn)單的例子來(lái)說明在iOS7.0和iOS6.1(以及更低版本)之間的適配問題(用的是xcode5.0,里邊有6.1和7.0兩個(gè)版本的sdk)
// 當(dāng)前系統(tǒng)支持的最小版本 min
__IPHONE_OS_VERSION_MIN_REQUIRED
// 當(dāng)前系統(tǒng)支持的最大版本 max
__IPHONE_OS_VERSION_MAX_ALLOWED
min的取值來(lái)自于你項(xiàng)目的deployment target, 即你的app愿意支持的最低版本
max的取值來(lái)自于你的sdk的版本, 比如現(xiàn)在我的是xcode6.1, sdk版本是iOS 8.1, 那么這個(gè)宏的值永遠(yuǎn)是80100,
先拋出一個(gè)問題 如何在iOS低版本(<8.0) 使用UIAlertViewController(ios8+)
新建一個(gè)工程,默認(rèn)的development target渐北,base sdk以及模擬器的版本都是7.0,在AppDelegate中的didFinishLaunchingWithOptions方法里寫下
self.window.tintColor = [UIColor redColor];
然后運(yùn)行范删,這樣是沒有任何錯(cuò)誤的矾利。接下來(lái)將development target,base sdk以及模擬器的版本都改成6.1(注意默認(rèn)的xcode是沒有6.1的sdk的信粮,需要自己另外導(dǎo)入)黔攒。然后運(yùn)行,就會(huì)報(bào)錯(cuò):
也就是說tintColor屬性在iOS6.1中根本就沒有强缘,在編譯時(shí)候就會(huì)出錯(cuò)亏钩。這時(shí)候如下加上判斷語(yǔ)句也是沒有用的,照樣報(bào)錯(cuò)(預(yù)處理欺旧,編譯姑丑,運(yùn)行的問題這里不再?gòu)U話)
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.window.tintColor = [UIColor redColor];
}
遇見這種情況只能加上預(yù)處理語(yǔ)句,這樣寫:
#ifdef __IPHONE_7_0
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.window.tintColor = [UIColor redColor];
}
#endif
或者
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.window.tintColor = [UIColor redColor];
}
#endif
在使用framework或者.a的時(shí)候需要注意
因?yàn)樵诰幾gframework或者.a的時(shí)候是依賴當(dāng)時(shí)編譯的環(huán)境決定的辞友,如使用iOS6的sdk可以將framework或者.a順利編譯通過栅哀,但是在真正生成app的時(shí)候需要保證編譯app時(shí)的sdk和編譯framework或者.a的sdk是一致的,且同時(shí)需要加入運(yùn)行時(shí)判斷([[[UIDevice currentDevice] systemVersion] floatValue]那個(gè))
說明:
1称龙、如果是使用低版本sdk編譯的(如iOS6)留拾,將最終的應(yīng)用安裝至高版本的設(shè)備上(iOS7的系統(tǒng)),此時(shí)應(yīng)該不會(huì)出現(xiàn)問題鲫尊,因?yàn)閕OS7兼容iOS6痴柔,但是無(wú)法使用iOS7特有的新功能,因?yàn)榇a被屏蔽了疫向。
2咳蔚、如果是使用高版本sdk編譯的(如iOS7),將最終的應(yīng)用安裝至低版本的設(shè)備上(iOS6的系統(tǒng))搔驼,此時(shí)如果不加入運(yùn)行時(shí)判斷就會(huì)出現(xiàn)問題(可能是crash)谈火。因?yàn)閼?yīng)用本身是用iOS7編譯的,并使用iOS7才有的新功能舌涨,而設(shè)備并不支持iOS7糯耍。
__IPHONE_OS_VERSION_MAX_ALLOWED編譯環(huán)境判斷,判斷當(dāng)前開發(fā)時(shí)使用的sdk的版本囊嘉。
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000
// 所使用的sdk為5.0以上的版本温技,在此的代碼在編譯時(shí)不會(huì)保存,但是允許在低版本ios系統(tǒng)的設(shè)備上運(yùn)行就會(huì)崩潰的
// 例如:你使用xcode6.1開發(fā)扭粱,SDK版本為8.1來(lái)開發(fā)項(xiàng)目舵鳞,并使用新API的新功能,在編譯時(shí)沒有問題焊刹,但是允許ios7系統(tǒng)的設(shè)備上就會(huì)崩潰
#else
//不能使用該API的代碼編寫
#endif
所以不能使用它來(lái)判斷你的項(xiàng)目是否支持低版本ios系統(tǒng)的設(shè)備
綜合以上系任,如要實(shí)現(xiàn)使用 ios8新的 UIAlertCtrl 的例子:
- 先判斷編譯環(huán)境, 以避免低版本SDK不認(rèn)識(shí)高版本SDK的api, 造成編譯錯(cuò)誤
- 在高版本SDK的條件內(nèi), 自行開始判斷SDK版本, 或responedToSelector都可以,來(lái)判斷是否使用高版本的api
- 在低版本條件內(nèi), 直接用低版本的api
// 編譯時(shí)判斷:檢查SDK版本
#if __IPHONE_OS_VERSION_MAX_ALLOWED > 80000
// 運(yùn)行時(shí)判斷:檢查當(dāng)前系統(tǒng)版本
if ([UIDevice currentDevice].systemVersion.floatValue > 8.0f) {
//這里寫UIAlertController
} else {
// 用舊的代替 UIAlertView
}
#else
// ...
#endif