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