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工程的targets的buildSetting中有一项Architectures,通过这一项我们设置工程所支持的设备类型。现在最新的Xcode版本4.5在新建工程的时候,默认值是“Standard(armv7,armv7s) ”,即支持iPhone3GS之后的所有设备。如果你写的程序需要支持iPhone3G的话,则需要编辑该选项,点击该选项选择others即可编辑,添加上armv6即可。如下图所示:
  
 

二、支持多系统版本

  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中多版本,多设备类型支持注意事项的更多相关文章

  1. IOS中input键盘事件支持的解决方法

    欢迎大家去我的网站详细查看http://genghongshuo.com.cn/ IOS中input键盘事件keyup.keydown.等支持不是很好, 用input监听键盘keyup事件,在安卓手机 ...

  2. iOS中如何知道app版本已更新

    主要用于程序升级,开启程序后是否显示新特性两个方面. 1.苹果app版本 苹果规定,程序的版本只能升不能降.例如1.0->1.1可以,1.1->1.0就不可以,不允许上架. 2.app版本 ...

  3. iOS中如何让TextView和TextField控件支持return键收起输入法

    TextView和TextField控件是iOS中负责接收用户输入的控件,那当用户输入完成时怎么收起面板呢? 1.TextView和TextField控件获得焦点之后的第一反应就是弹出输入法面板: 2 ...

  4. ios 中不new Date 的格式 不支持年月日 以‘-’ 分割的格式

    new Date("2018-1-5") 在 ios 中显示 invalid date - 换做 / 则可以顺利显示 new Date("2018/1/5")

  5. iOS中支付宝集成

    iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...

  6. 在iOS中使用ZXing库[转]

    前言 ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0).它不但支持众多的条码格式,而且有各种语言的实现版本,它支持的语言包括:Java, C++, C#, ...

  7. iOS中JSONModel的使用

    iOS中JSONModel的使用   流弊的JSON数据模型框架 https://github.com/jsonmodel/jsonmodel 版本 1.3.0 如果你喜欢JSONModel,并且使用 ...

  8. iOS中集成ijkplayer视频直播框架

    ijkplayer 是一款做视频直播的框架, 基于ffmpeg, 支持 Android 和 iOS, 网上也有很多集成说明, 但是个人觉得还是不够详细, 在这里详细的讲一下在 iOS 中如何集成ijk ...

  9. iOS中dyld缓存的实现原理是怎样的?

    在iOS开发中,为了提升系统的安全性,很多系统库文件都被打包到一个缓存的文件当中即dyld缓存,那大家对dyld缓存了解多少呢?今天小编将和大家分享的就是一位iOS大神对dyld缓存的使用分析,一起来 ...

随机推荐

  1. Linux-vmware tools安装与cdrom挂载

    前述 昨天想直接复制虚拟机centos系统中命令行的内容到主机的txt文档上进行保存,发现不能实现虚拟机与主机之间的直接通讯,后来查资料发现原来是由于我的虚拟机没有安装vwmare tools的缘故. ...

  2. [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性

    前言 下面就开始总结C#4.0的一些变化了, 也是这本书中最后的一点内容了, 这一部分终于要更新完了. 同时感觉再来读第二遍也有不一样的收获. 今天很嗨的是武汉下雪了,明天周六,一切都是这么美好.哈哈 ...

  3. IOS行货自动打包

    通常打包采用xcodebuild和xcrun两个命令,xcodebuild负责编译,xcrun负责将app打成ipa.   常见步骤如下: 1.清理工程 /usr/bin/xcodebuild -ta ...

  4. Swift 中范围和区间如何使用?

    虽然现在swift语言已经发展到了2.0版了,但是相信很多学习iOS开发的童鞋仍对swift语言存在各种各样的疑问,今天小编将为大家详细介绍swift中的范围和区间,下面我们一起来看看吧. Range ...

  5. 闲暇时间开发的个人app

    最近一段时间公司不是很忙,晚上基本没怎么加班.所以自己利用晚上在家的时间开发了一个app(奇趣营),其实自从转android开发以来,就有想过要自己开发一个app.一方面可以提升自己的经验:另一方面可 ...

  6. GTD时间管理(1)---捕获搜集

    前一段时间感觉自己的整个思路很混乱,每一天觉得自己有很多事情很多,但是坐着做着不知道自己做了多少,做项目的时候做着做着时常东想西想.我个人觉得这种想法是不对经的. 于是在google上都出去寻找这方面 ...

  7. int android.graphics.Bitmap.getRowBytes()

    int android.graphics.Bitmap.getRowBytes() Return the number of bytes between rows in the bitmap's pi ...

  8. Selenium 3 -how to locate the chromedriver and geckodriver place?

    Maybe you met these exceptions sometimes: 1. Chrome Driver The path to the driver executable must be ...

  9. mysql中You can’t specify target table for update in FROM clause错误解决方法

    mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表( ...

  10. MySQL vs. MongoDB: Choosing a Data Management Solution

    原文地址:http://www.javacodegeeks.com/2015/07/mysql-vs-mongodb.html 1. Introduction It would be fair to ...