极少数应用程序很“奢侈”的只支持最新版本的 iOS。 设置一个较低的部署目标以及基于特定 iOS 版本的代码分支通常是很有必要的。虽然苹果公司的信息有些矛盾,还是有各种办法来完成这个。最近在这条 tweet上看到有人警告说,不要这样做:
#define IsIOS7 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=7)
GitHub 搜索显示,有超过 8000 的结果调用了 substringToIndex:1 。所有这些代码碰到 iOS 10 就“懵逼”了。因为 iOS 10 会被检测成 iOS 1 了,估计只有在越狱的应用中才会出现吧。
iOS 8 中,终于有了一些改进!现在 NSProcessInfo 有一个新的 operatingSystemVersion 方法,更重要的是还有 - (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version 方法来检查。
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion = 9, .minorVersion = 1, .patchVersion = 0}]) {
NSLog(@"Hello from > iOS 9.1");
}
最开始写的时候还是 iOS 4,随着一系列新 iOS 版本的发布,它也不断的在改进。那个时候还没有专门的 API 来检测版本,许多应用采用类似下面的代码:
if ([[[UIDevice currentDevice] systemVersion] isEqualToString:@"7.0"]) {
//do stuff
}
这样用不好,所以我们从来没这样用过。比较字符串速度可能很快,但是在这种情况下是个错误的选择。正确的做法是像下面这样:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) \
([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
...
}
这样又太笨重了,容易出错。有种更简单的方法。我们可以用 NSFoundationVersionNumber(或者 kCFCoreFoundationVersionNumber)来比较。系统检测开销降低到一个简单的 if 比较。不需要调用其它方法,所以它效率极高,即使在紧凑的循环中表现也不错。
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) {
// do stuff for iOS 9 and newer
}
else {
// do stuff for older versions than iOS 9
}
现在可以用更少的代码完成同样的事:
if #available(iOS 10.0, *) {
// modern code
} else {
// Fallback on earlier versions
}
网友评论