• 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工程的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 

  • 相关阅读:
    changing a pointer rather than erasing memory cells
    验证码识别 edge enhancement 轮廓增强 region finding 区域查找
    Manipulating Data Structures
    passing parameters by value is inefficient when the parameters represent large blocks of data
    Aliasing 走样
    Artificial Intelligence Research Methodologies 人工智能研究方法
    Thread safety
    include pointers as a primitive data type
    flat file
    functional cohesion
  • 原文地址:https://www.cnblogs.com/bmate/p/3460417.html
Copyright © 2020-2023  润新知