【IOS】宏定義 系統(tǒng)版本 判定 請不要用Availability.h中的宏!

當(dāng)需要判斷iOS系統(tǒng)版本的時候,相信很多人都會這么干:

#define SystemVersion [[UIDevice currentDevice] systemVersion].floatValue

曾經(jīng)看到一篇文章告訴說

在Availability.h中已經(jīng)定義了很多系統(tǒng)的宏:

Paste_Image.png

然后使用:

#ifdef __IPHONE_7_0
  //iOS7以后的新特性代碼
#endif

或者是使用:

if(__IPHONE_7_0)
  //iOS7的新特性代碼
else
  //不能使用新特性

就搞定了。

如果用戶用的是 IOS8的系統(tǒng),
那么他的這個Availability.h文件中肯定沒有 IOS9的定義,
所以,可以用 __IPHONE_9_0來判斷用戶是不是高于一個IOS9版本

但是!以下經(jīng)過被坑的血的教訓(xùn)得出來!

注意:經(jīng)過實(shí)驗(yàn)證明,上邊的方法無效,這個宏是跟你的編譯時候SDK 版本有關(guān),跟你運(yùn)行時候沒有關(guān)系,所以不要去用!!!

注意:經(jīng)過實(shí)驗(yàn)證明,上邊的方法無效,這個宏是跟你的編譯時候SDK 版本有關(guān),跟你運(yùn)行時候沒有關(guān)系,所以不要去用!!!

注意:經(jīng)過實(shí)驗(yàn)證明,上邊的方法無效,這個宏是跟你的編譯時候SDK 版本有關(guān),跟你運(yùn)行時候沒有關(guān)系,所以不要去用!!!

先來兩段代碼:

片段1:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000
    //you can use iOS 5 APIs here because the SDK supports them
    //but the code may still crash if run on an iOS 4 device
#else
    //this code can’t use iOS 5 APIs as the SDK version doesn’t support them
#endif

片段2:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000
    //minimum deployment target is 5.0, so it’s safe to use iOS 5-only code
#else
    //you can use iOS5 APIs, but the code will need to be backwards
    //compatible or it will crash when run on an iOS 4 device
#endif

如果碰到這個場景, 需要使用UIAlertViewController(iOS8+),我能用上述哪種寫法呢?
答案是, 都不行.
__IPHONE_OS_VERSION_MAX_ALLOWED的取值來自于你的編譯時候的SDK的版本, 比如現(xiàn)在我的是Xcode8.1, SDK版本是iOS 10.3, 那么這個宏的值永遠(yuǎn)是100300, 也就是說, 會直接使用UIAlertViewController, 如果這個app跑在了iOS 7上, 就掛了.
所以單純這么寫只解決了你的iOS8的API跑到低版本的Xcode的時候不會報編譯錯誤.

__IPHONE_OS_VERSION_MIN_REQUIRED的取值來自于你項(xiàng)目的deployment target, 即你的APP愿意支持的最低版本.
從這個角度來說, 片段2寫法只對做可移植的包的開發(fā)團(tuán)隊(duì)有用, 即不知道使用方會將deployment target設(shè)成幾.
而沒有這個需求的, 這種寫法就浪費(fèi)了(因?yàn)榧僭O(shè)自己的deployment是7.0,然后你想要在里面判斷是7還是8來使用UIAlertViewController,還是UIAlertView。那么就是不可行的。因?yàn)閐eployment都是7,不管是7還是8的系統(tǒng),出來的結(jié)果都是7,所以你始終使用的是UIALertView) 即你既然設(shè)定了最低支持iOS6, 那么還寫一段代碼來判斷如果最低支持iOS7的情況下應(yīng)該怎么做干嘛呢?

//  使用Xcode8,再把target設(shè)成9.0,下面代碼會打印出100000 90000
    NSLog(@"%d",__IPHONE_OS_VERSION_MAX_ALLOWED);
    NSLog(@"%d",__IPHONE_OS_VERSION_MIN_REQUIRED);

那么我上面的問題(即我想使用新的API,但app又要支持舊的iOS版本)怎么解決? >>>>> 組合!

我先判斷編譯環(huán)境, 以避免低版本SDK不認(rèn)識高版本SDK的API, 造成編譯錯誤(片段1)
在高版本SDK的條件內(nèi), 自行開始判斷SDK版本, 或responedToSelector都可以,來判斷是否使用高版本的api
在低版本條件內(nèi), 直接用低版本的API

片段2的場景很明確了,只針對最低的SDK版本寫代碼,這樣使用你這個庫的用戶不管把deployment target設(shè)成多少,都是看不到錯誤的, 只是, 這就使得這種代碼執(zhí)行起來, 永遠(yuǎn)用的是最舊的API

Demo地址:https://github.com/yuying2012/WJDStudyLibrary
這是一個大工程,請從工程中尋找相關(guān)模塊代碼.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容