【问题标题】:How to determine if compiling for 64-bit iOS in Xcode如何确定是否在 Xcode 中为 64 位 iOS 编译
【发布时间】:2013-09-22 13:15:42
【问题描述】:

考虑以下函数

CGSize CGSizeIntegral(CGSize size)
{
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

CGSize实际上是由两个CGFloat组成,而CGFloat的定义会根据架构而变化:

typedef float CGFloat;// 32-bit
typedef double CGFloat;// 64-bit

所以,上面的代码在 64 位系统上是错误的,需要用类似的东西更新

CGSize CGSizeIntegral(CGSize size)
{
#if 64_bit
    return CGSizeMake(ceil(size.width), ceil(size.height));
#else
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
#endif
}

这肯定有一个编译器宏/常量(例如,对于 Mac,我们可以使用 INTEL_X86),但我无法在 64-bit transition guide 中找到它。

我如何确定构建的架构是什么?

【问题讨论】:

    标签: ios 32bit-64bit ios7


    【解决方案1】:

    要确定您是否正在为 64 位编译,请使用 __LP64__

    #if __LP64__
        return CGSizeMake(ceil(size.width), ceil(size.height));
    #else
        return CGSizeMake(ceilf(size.width), ceilf(size.height));
    #endif
    

    __LP64__ 代表“long 和指针是 64 位”,并且与架构无关。

    根据您的过渡指南,它也适用于 iOS:

    编译器在为 64 位编译时定义了 __LP64__ 宏 运行时。

    但是,处理您的用例的首选方法是使用CGFLOAT_IS_DOUBLE。不能保证__LP64__ 总是意味着CGFloat 是双精度,但CGFLOAT_IS_DOUBLE 可以保证。

    #if CGFLOAT_IS_DOUBLE
        return CGSizeMake(ceil(size.width), ceil(size.height));
    #else
        return CGSizeMake(ceilf(size.width), ceilf(size.height));
    #endif
    

    【讨论】:

    • 我现在在文档中看到了,谢谢。这似乎是正确的,但至少在我自己的测试中(仅限模拟器,这里还没有 iPhone 5S...)即使在为 64 构建时,我也会执行非 LP64 代码-少量。我看到对它的引用散布在 SDK 中,但实际上似乎并没有在任何地方定义(这可以解释行为)。 XCode 5 GM 种子。
    • Xcode 并未更改架构以在“架构”的实际构建设置中包含 64 位。
    • CGFLOAT_IS_DOUBLE 应该被选中而不是 __LP64__
    • 快速提问,如果应用程序不支持 arm64 并且我们在代码中进行了此检查,如果我们在 64 位设备上运行,它将始终执行 32 位版本,对吗?因为它不支持 64 位,所以它永远不会为它编译,所以 LP64 永远不会被定义 - 对吗?
    • 最终@rpetrich 是正确的。 __LP64__ 的定义可能不会很快改变,但它可能会改变,所以CGFLOAT_IS_DOUBLE 是这种情况下的更好选择。我更新了我的答案以反映这一点。
    【解决方案2】:

    对于 Swift,忽略 OP 涉及 CGFloats 等的具体问题,以下可能更迅速:

      #if (arch(i386) || arch(arm))
         ....  // For 32-bit systems
      #else
         ....  // For 64-bit systems
      #endif
    
    
      #if (arch(x86_64) || arch(arm64))
         ....  // For 64-bit systems
      #endif
    

    另一方面,上述答案中讨论的编译时常量也可以在 Swift 中使用,如果它们是首选的话。

    这主要是从这里复制的:https://stackoverflow.com/a/24869607/253938

    关于这些 Swift 编译时常量的 Apple 文档在这里: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html(在页面的最底部)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2015-06-06
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多