ObjectiveC测试,如果int是长还是不/ CGFloat的是float或double [英] ObjectiveC test if int is long or not / CGFloat is float or double

查看:307
本文介绍了ObjectiveC测试,如果int是长还是不/ CGFloat的是float或double的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

苹果公司现在要求所有iOS code是32/64位二元。这是伟大的 - 除了有他们的一些图书馆的不完全支持的两重性

Apple now requires all iOS code to be 32/64 bit dualistic. That's great - except there's a few of their libraries that don't fully support the duality.

例如。一个项目使用NSScanner,支持scanInteger(正确的),但没有scanCGFloat - 而不是你要scanFloat或scanDouble(中文codeD的方法名!)

e.g. one project uses NSScanner, which supports "scanInteger" (correct) but no "scanCGFloat" - instead you have to "scanFloat" or "scanDouble" (encoded in the method names!).

更新:NSScanner比我认识一个厉害的例子;它需要指针作为ARGS。

UPDATE: NSScanner is a nastier example than I realised; it takes pointers as args.

- (BOOL)scanFloat:(float *)result;
- (BOOL)scanDouble:(double *)result;

...啊。

这影响了一大堆东西 - 另一个例子就是math.h中(类似:浮动VS双恩是函数名codeD),虽然你至少可以切换到tgmath.h和摆脱类型是,在该名愚蠢。

It affects a whole bunch of stuff - another example is math.h (similarly: float vs double is encoded in function names), although there you can at least switch to tgmath.h and get rid of the "type-is-in-the-name" silliness.

什么是正确的,一般情况下,解决这个问题的?

What's the correct, general, solution to this problem?

推荐答案

C11引入了一个新的功能一般的选择,它可以被用来
让编译器选择合适的方法,这取决于 CGFloat的的类型。

C11 has introduced a new feature "Generic selection" that can be used to let the compiler choose the right method, depending on the type of CGFloat.

@implementation NSScanner (MyCategory)

-(BOOL) myScanCGFloat:(CGFloat *)cgFloatValue
{
    return _Generic(*cgFloatValue,
                    double: [self scanDouble:(double *)cgFloatValue],
                    float: [self scanFloat:(float *)cgFloatValue]);
}

@end

注:

  • The _Generic keyword is described in "6.5.1.1 Generic selection" of the C11 standard (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). Another description is here: http://www.robertgamble.net/2012/01/c11-generic-selections.html.
  • Selecting the matching code is done by the compiler, not at runtime.
  • The selection checks if CGFloat is compatible to float or double, not if the current target architecture is 32-bit or 64-bit.
  • This solution does not depend on any preprocessor macros.
  • As of Xcode 5.0.2, Clang supports the _Generic keyword, even in the default GNU99 mode. I have not tested earlier Xcode/Clang versions.

previous答案:一种可能的解决办法是不要模仿 CGFloat的定义
并让preprocessor选择正确的版本:

Previous answer: One possible solution would be do mimic the definition of CGFloat and let the preprocessor choose the correct version:

CGFloat f;

#if __LP64__
    [scanner scanDouble:&f];
#else
    [scanner scanFloat:&f];
#endif

或者你定义自定义宏:

Or you define a custom macro:

#if __LP64__
#define scanCGFloat scanDouble
#else
#define scanCGFloat scanFloat
#endif

// ...
CFFloat f;
[scanner scanCGFloat:&f];

另外,使用一个临时变量:

Alternatively, use a temporary variable:

double tmp;
[scanner scanDouble:&tmp];
f = tmp;

这篇关于ObjectiveC测试,如果int是长还是不/ CGFloat的是float或double的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆