IOS中多版本,多设备类型支持注意事项
IOS系统从07年出来,到现在也有6年了,每年发布一次到两次新的设备,从iPhone1,iPhone2 ... iPhone4s再到最新的iPhone5。硬件在升级的过程中CPU的架构也可能发生变化,如最早的armv6,armv7再带最新的iPhone5所以用的armv7s。同时伴随每一次硬件升级,系统都会做一次大版本的升级,目前最新的版本已经到了6.x了。
每次系统升级的时候,总有一些用户会因为各种原因不愿或者不能升级到最新的系统。这就意味着,如果我们的程序要让尽可能多的人使用,就得支持尽可能多的硬件架构及系统版本。如果我们写的程序和硬件打交道比较少的话,要做的事也就是配置一下工程选项中的Architectures,在其中添加上我们要支持的硬件架构就好了。然而每次系统的升级都会伴随这很多新的API,Framework的引入,以及部分老的API的废弃。也就说我们要支持的系统版本越多,工作量也就越大,所以我们通常会根据工作量和系统版本的分布情况做出取舍。现在AppStore上基本上的程序一般最多也就支持IOS 4.3的系统了吧,我做的上个项目PowerCam记得也是从4.0版本开始支持。
下面我们分别从两个方面讨论一下:
一、支持多设备类型
不同的设备CPU指令集可能是不同的,这也就导致了其支持的框架可能不同。例如iPhone3G及之前版本的设备的CPU只支持armv6的指令集,导致了这些设备只支持OpenGL ES 1.1版本,所有iPad及iPhone3GS之后的所有设备都采用armv7及armv7s(iPhone5,iPad4采用)指令集,因此既可以支持OpenGL ES 1.1和2.0。
二、支持多系统版本
Xcode在工程的编译选项中,我们可以看到两个选项:Base SDK和Deployment Target,第一个选项是用来设置我们项目是基于哪个版本的SDK开发,第二选项是用来设置我们的项目最低可以部署到哪一个系统运行。
Xcode新建的工程中通常都会采用最用的SDK以及支持到最新的版本。因为我们要既支持新的版本,同事兼顾的老的版本,为了能够利用上新版本中新的特性,所以最好选择最新的SDK,这一项通常不用改,维持原样就好。如果要支持叫早的系统版本,则需要修改Deployment Target选项。如下图所示,我们设置项目需要最老的版本为IOS 4.3。
到这儿就设置完了,Xcode会根据我们的设置进行编译打包。在这里我们讨论一下Xcode是如何使用了最新版本的SDK,却可以支持到较老的系统版本呢?查阅文档SDK Compatibility Guide发现,在程序打包的时候,Xcode只是将一些导出符号打到我们的程序包中,具体到运行时会根据实际的设备的系统版本进行匹配。文档中有一个图可以解释Base SDK和Deployment Target之间是如何运作的,如下图:
该图是以Mac OS工程为例的,不过原理是一样的。意思是对于我们支持部署的版本之前的所有API,我们都是可以无条件使用的(当前在新的版本中最好使用新的API),在我们支持部署的版本和我们开发所基于的SDK版本之间的API,能否使用取决于我们的APP具体运行的系统版本。
在系统版本升级的过程中,通常会添加一些新的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
IOS中多版本,多设备类型支持注意事项的更多相关文章
- IOS中input键盘事件支持的解决方法
欢迎大家去我的网站详细查看http://genghongshuo.com.cn/ IOS中input键盘事件keyup.keydown.等支持不是很好, 用input监听键盘keyup事件,在安卓手机 ...
- iOS中如何知道app版本已更新
主要用于程序升级,开启程序后是否显示新特性两个方面. 1.苹果app版本 苹果规定,程序的版本只能升不能降.例如1.0->1.1可以,1.1->1.0就不可以,不允许上架. 2.app版本 ...
- iOS中如何让TextView和TextField控件支持return键收起输入法
TextView和TextField控件是iOS中负责接收用户输入的控件,那当用户输入完成时怎么收起面板呢? 1.TextView和TextField控件获得焦点之后的第一反应就是弹出输入法面板: 2 ...
- ios 中不new Date 的格式 不支持年月日 以‘-’ 分割的格式
new Date("2018-1-5") 在 ios 中显示 invalid date - 换做 / 则可以顺利显示 new Date("2018/1/5")
- iOS中支付宝集成
iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...
- 在iOS中使用ZXing库[转]
前言 ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0).它不但支持众多的条码格式,而且有各种语言的实现版本,它支持的语言包括:Java, C++, C#, ...
- iOS中JSONModel的使用
iOS中JSONModel的使用 流弊的JSON数据模型框架 https://github.com/jsonmodel/jsonmodel 版本 1.3.0 如果你喜欢JSONModel,并且使用 ...
- iOS中集成ijkplayer视频直播框架
ijkplayer 是一款做视频直播的框架, 基于ffmpeg, 支持 Android 和 iOS, 网上也有很多集成说明, 但是个人觉得还是不够详细, 在这里详细的讲一下在 iOS 中如何集成ijk ...
- iOS中dyld缓存的实现原理是怎样的?
在iOS开发中,为了提升系统的安全性,很多系统库文件都被打包到一个缓存的文件当中即dyld缓存,那大家对dyld缓存了解多少呢?今天小编将和大家分享的就是一位iOS大神对dyld缓存的使用分析,一起来 ...
随机推荐
- phpcms v9二次开发笔记
phpcms是基于MVC结构的. 安装: 下载phpcms_v9.5.9_UTF8.zip:新建目录phpcms,将压缩包里install_package目录下所有文件复制到phpcms目录.浏览器输 ...
- JS获取元素CSS值的各种方法分析
先来看一个实例:如何获取一个没有设置大小的字体? <!DOCTYPE html> <html lang="en"> <head> <met ...
- paip.汉字简化大法总结
paip.汉字简化大法总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/attilax ...
- 匿名管道读取CMD回显信息
之前用了很坑爹的做法去读取了cmd命令的回显信息,现在发现了用匿名管道的实现方法,由于楼主没有学过Windows核心编程,找了一个代码来凑数 存下来以后研究 #include <windows. ...
- [mongodb-10gen]ubuntu下安装方法
由于自己老是不死心,所以还是继续在UBUNTU下开始我的GOLANG,今天发现服务源很快一下子就把GO的源代码从GoogleProject上给hg回来了,所以今天才查了一下在UBUNTU下安装Mong ...
- python ide: pycharm
1, 设置python路径 2,运行py文件 https://www.jetbrains.com/help/pycharm/2016.1/creating-and-running-your-first ...
- 动态变化的OO设计
今天看到个题目:对象会动态的变化. 游戏精灵,有人和神仙,但是随着人的不断积分,会升级为神仙:神仙也可能会因为积分的减少而降级为人.这种情况怎么画出个类图来. 这是第一版的设计,正常思维.人和神仙都是 ...
- PCM音频设备的操作(转)
对音频设备的操作主要是初始化音频设备以及往音频设备发送 PCM(Pulse Code Modulation)数据.为了方便,本文使用 ALSA(Advanced Linux Sound Archite ...
- [转] Autofac创建实例的方法总结
1.InstancePerDependency 对每一个依赖或每一次调用创建一个新的唯一的实例.这也是默认的创建实例的方式. 官方文档解释:Configure the component so tha ...
- linux 文件夹说明,用户添加删除,不熟悉的命令
一.Linux 根目录下的文件夹说明 usr 程序默认安装路径,相当于windows的 program 附显示当前所处位置:pwd 二.用户 用户添加:useradd 用户名 passwd 用户名 u ...