16

考虑以下函数

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

CGSize实际上由两个CGFloats 和 s 组成,而CGFloats 的定义根据架构而有所不同:

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
}

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

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

4

2 回答 2

33

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

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

__LP64__代表“longs and pointers are 64-bit”并且是架构中立的。

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

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

但是,处理用例的首选方法是使用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
于 2013-09-17T22:48:33.393 回答
4

对于 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 (在页面的最底部)。

于 2017-03-10T08:02:59.853 回答