iOS版本
1.靜態檢查
靜態檢查,即在編譯時段就檢查當前SDK編譯與構建應用是否能使用某個API或已經不支持某個API。
編譯常量
__IPHONE_OS_VERSION_MIN_REQUIRED
用來判斷是否當前SDK版本“仍然”支持或具有某些功能。
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 //minimum deployment target is 8.0, so it’s safe to use iOS 8-only code 當前SDK最小支持的設備系統,即8.0,所以在iOS 8.0設備上是安全的 #else //you can use iOS8 APIs, but the code will need to be backwards //compatible or it will crash when run on an iOS 7 device 你仍然可以使用iOS 8的API,但是在iOS 7的設備上可能會crash. #endif
__IPHONE_OS_VERSION_MAX_ALLOWED
用來判斷是否當前版本“開始”支持或具有某些功能;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 //you can use iOS 10 APIs here because the SDK supports them //but the code may still crash if run on an iOS 8 device 可以使用最新的iOS 10的API,開始支持的新功能。但是仍然可能會在iOS 8的設備上crash。 #else //this code can’t use iOS 10 APIs as the SDK version doesn’t support them 不能使用iOS 10的API,只能使用iOS 10之前的。 #endif
針對Xcode的舊版本,或者設備上的就版本,不存在相應的宏,采用如下定義:
#ifndef __IPHONE_10_0 #define __IPHONE_10_0 100000 #endif #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #else #endif
2.動態檢查
CoreFoudation/NSFoundation版本宏
類似於iOS 系統版本宏,系統還給出了CoreFoudation和NSFoudation宏,並且給出了kCFCoreFoundationVersionNumber和NSFoundationVersionNumber兩個值。這兩個值均是double值。
在iOS10.2.1系統上,以上兩個值,分別是:1348.220000、1349.130000。
在Debug下,兩個值的存儲po出來分別是:1348.22、1349.1300000000001。
kCFCoreFoundationVersionNumber
詳見 CoreFoundatin/CFBase.h中定義。
NSFoundationVersionNumber
詳見 Foundation/NSObjRuntime.h中定義。
針對上面的宏,寫起來復雜,所以可以定義一個宏,來簡化書寫:
#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_10_0 #define kCFCoreFoundationVersionNumber_iPhoneOS_10_0 1299 #endif #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 #define IF_IOS10_OR_GREATER(...) if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_10_0) { __VA_ARGS__ } #else #define IF_IOS10_OR_GREATER(...) #endif #define IF_PRE_IOS10(...) if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_10_0) { __VA_ARGS__ }
IF_IOS10_OR_GREATER
和IF_PRE_IOS10
就可以在使用中快捷調用。
IF_IOS10_OR_GREATER ( //iOS 10 code here );
然而,即使上面這種方法可以簡單的檢查系統版本,你仍然無法保證絕對正確,因為你會發現以上宏中不同的系統版本中存在相同的值。
缺陷:當你要判斷那些剛好存在相同值的版本的時候,也是一個危險的判斷。
3.檢查運行的iOS 系統版本
if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 10.0) { }
註意:上面的判斷方法,在判斷整數版本的時候,使用起來挺方便,也不會出什麽大問題。但是仍然是極其危險的。因為float在計算機中的存儲,是近似而非精確。
比如,最新的iOS 10.2.1系統,有以下一段代碼:
NSString *version = [[UIDevice currentDevice] systemVersion]; int int_ver = [version intValue]; float float_ver = [version floatValue]; NSLog(@"%@-%d-%f",version,int_ver,float_ver);
打印出來如下的結果:
10.2.1-10-10.200000
可以看出,10.2.1打印出來的floatValue值,是【10.20000】,這還算小事。更為致命的是,在控制臺調試時發現:
所以,假如比較10.2.1和10.2.2比較,就很難得出結果。
鑒於此,以上方法不推薦使用!最好不用!
那麽,什麽是好的運行時判斷系統的方法呢?
定義判斷版本的宏:
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
但是,由於NSString的compare方法本身的缺陷:
NSInteger compareResult = [@"10.0" compare:@"10" options:NSNumericSearch];
遺憾的是,上面的系統版本判斷也是有漏洞的。但是相對於之前的漏洞,這個漏洞似乎可以接受。上面返回的結果:NSOrderedDescending,即10.0相比於10是低版本。
4.iOS 8之後,NSOperatingSystemVersion
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
NSProcessInfo
還提供了:
NSOperatingSystemVersion v = (NSOperatingSystemVersion){8,1,3}; if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v]) { }
以上這個方法,只有在iOS 8之後,但是對於一些超級APP,仍然在支持iOS 7,所以也就無能為力了。
轉自
iOS版本