【问题标题】:How to target a specific iPhone version?如何定位特定的 iPhone 版本?
【发布时间】:2010-10-23 15:18:52
【问题描述】:

我有一些代码我只想在最新的 iPhone SDK (3.0) 上执行,但是我似乎无法找到一种只针对 3.0 并忽略 2.2.1 等的方法。有一个 ifdef 语句,但它似乎只是覆盖了整个 iPhone:

#if TARGET_OS_IPHONE

感谢任何帮助。

【问题讨论】:

    标签: iphone


    【解决方案1】:

    更新:当使用 Xcode 4 在 iPhone (4.3.1) 上构建和运行时,这似乎不再适合我。另外,我得到__IPHONE_OS_VERSION_MIN_REQUIRED = 30200

    The iPhone Developer's Cookbook说你也可以这样做:

    #ifdef _USE_OS_4_OR_LATER
        // code to compile for 4.0 or later
    #else
        // code to compile for pre-4.0
    #endif
    

    而且,它似乎对我有用。 :)

    【讨论】:

    • 我找不到在 Foundation 中可能定义的位置。它在哪里?
    【解决方案2】:

    我会小心 floatValue 返回结果:

    [[[UIDevice currentDevice] systemVersion] floatValue]
    

    与任何花车一样,它可能并不完全符合您的期望。在我的系统上运行上述内容时,我很困惑为什么我的条件语句没有执行,我注意到返回的值是:

    3.20000005
    

    在这里推荐解决方案:How to check iOS version?

    摘录:

    NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"3.1.3" options: NSNumericSearch];
    if (order == NSOrderedSame || order == NSOrderedDescending) {
        // OS version >= 3.1.3
    } else {
        // OS version < 3.1.3
    }
    

    【讨论】:

    • 3.2.00..005 仍然是doubleValue 的问题吗?
    • @BenC.R.Leggiero 它应该是。无论您使用多少精度,都不可能用二进制精确表示 3.2。
    • @BrennanVincent 我认为您的意思是 IEEE 浮点数,因为使用 NSDecimalNumber 表示是微不足道的
    • @BenLeggiero 我说的是二进制。 NSDecimalNumber 不是“二进制”;它是二进制编码的十进制。我的陈述是关于数学,而不是计算机技术。 double 是二进制的,所以它在数学上不可能精确地表示 3.2。
    【解决方案3】:

    你也可以这样做:

    #ifdef __IPHONE_3_0
    // 3.0 code here
    #endif
    

    【讨论】:

    • 请注意,去那里的代码是3.0+,而不仅仅是3.0。
    【解决方案4】:

    好吧,我的两分钱:

    如何使用最新版本(例如 3.0)构建您的应用程序,以便您可以利用所有新的和酷的 API,并将部署目标指定为您想要支持的最新版本,以便那些没有花时间的人升级他们的设备仍将运行您的应用程序。在这种情况下,如上所示,您需要检查 SDK 的最新版本并提供备用功能以使您的应用程序向后兼容。

    问候, 哈迪克

    【讨论】:

    • 这如何帮助只在 iOS 3 或更高版本上运行一段代码?
    【解决方案5】:

    您可以使用此 #define 更改为每个 SDK 构建的内容...

    #if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_2_2
    // iPhone 3.0 code here
    #endif
    

    并在运行时执行此操作以运行 3.0 及更高版本的代码:

    float version = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (version >= 3.0)
        {
        // iPhone 3.0 code here
        }
    

    【讨论】:

    • 需要注意的一点是,针对模拟器和设备进行编译可能会导致这些宏发生惊人的变化。为模拟器 SDK 2.2.1 编译时,我得到 __IPHONE_OS_VERSION_MIN_REQUIRED = 20000。但是,在为设备编译时,我得到 __IPHONE_OS_VERSION_MIN_REQUIRED = 20201,这打破了您在上面定义的条件。我目前正在使用普通的“#ifdef __IPHONE_3_0”来隔离仅适用于 3.0 或更高版本的代码。之所以可行,是因为宏直到 3.0 SDK 才定义。
    • 小心运行时代码。通过调用floatValue,你只会得到3.20000,即使实际版本是3.2.2。
    • 当我使用 Xcode 4 在 iPhone (4.3.1) 上构建和运行时,为什么会得到 __IPHONE_OS_VERSION_MIN_REQUIRED = 30200?
    • 您答案中的运行时代码完全错误。浮点值和字符串有不同的顺序:3.10 &lt; 3.2,但"3.10" &gt; "3.2"。此外,版本字符串可能包含两个以上的组件(例如,5.0.1,在许多应用程序中用于从 iCloud 备份中排除文件)。进行版本检查的正确方法是使用[systemVersion compare:version options:NSNumericSearch]
    • 版本号根本不是浮点数或十进制数。版本号是整数,由点字符分隔。
    【解决方案6】:

    我相当肯定 OP 上的评论总结了这一点。你不能。因为编译时指令不能做出运行时决定。在 Xcode 中,如果您以 3.0 为目标,它将无法在 2.2.1 手机上运行。如果您以 2.2.1 为目标,它将无法编译,因为您那里有 3.0 特定的代码。

    唯一真正的解决方案是应用的两个版本,其中一个针对 3.0 编译,另一个针对 2.2.1。

    【讨论】:

    • 第一个:OP 实际上并不排除编译时检查。第二:您给定的规则有例外。例如,MPMoviePlayerController 存在于 3.0 和 3.2 上,但在 3.2(和 4.0)上的工作方式不同 - 为了在两个平台上正确支持它,我发现使用 runtime-os-version-check 非常方便。在我的特殊情况下,省略此检查仍会导致在两个平台上都正确构建,但会在低于 3.2 的任何平台上崩溃。
    【解决方案7】:

    使用从this answer 添加 OTHER_CFLAGS = "-g3 -save-temps -dD" 的技巧,我发现定义 __IPHONE_OS_VERSION_MIN_REQUIRED 20000 的项目针对 2.2.1。也许这会奏效?

    【讨论】:

      【解决方案8】:

      它在 Xcode 的构建选项中。左上角的下拉菜单显示“myapp - 3.0 | Debug”之类的内容 选择你想要的构建,然后就完成了。

      【讨论】:

      • 该方法的问题是我希望我的应用程序也可以在 2.2.1 上运行,而只有这一行代码在 3.0 上运行。你的方法意味着我必须放弃对 2.2x 的支持。
      • 我现在明白你的意思了,很棘手,但到时候你也许可以进行精确检查。说检查标题中的定义。
      猜你喜欢
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-29
      • 2011-01-26
      • 2015-01-09
      • 1970-01-01
      • 2015-10-05
      相关资源
      最近更新 更多