简体   繁体   English

从 NSNumber 获取 CGFloat 的最常见和正确的做法是什么?

[英]What is most common and correct practice to get a CGFloat from an NSNumber?

The working code for me is something like:我的工作代码是这样的:

NSNumber *n = @42.42;
CGFloat cgf = 0; 
CFNumberRef cfn = CFBridgingRetain(n);
CFNumberGetValue(cfn, kCFNumberCGFloatType, &cgf);
CFRelease(cfn);

There could be also也可能有

CGFloat cgf = (CGFLOAT_IS_DOUBLE) ? [n doubleValue] : [n floatValue];

But this smells even uglier for me.但这对我来说更难闻。

It seems to me there should be better API for doing such a common thing.在我看来,应该有更好的 API 来做这种常见的事情。 Are there any?有吗?

This will get the correct result in any case:在任何情况下,这都会得到正确的结果:

 NSNumber *n = @42.42;
 CGFloat cgf = [n doubleValue];

because CGFloat is either float or double .因为CGFloatfloatdouble


NSNumber does not have a CGFloatValue method. NSNumber没有CGFloatValue方法。 You could define one using the toll-free bridge to CFNumberRef :您可以使用到CFNumberRef的免费桥接来定义一个:

@interface NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue;
@end

@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
    CGFloat result;
    CFNumberGetValue((__bridge CFNumberRef)(self), kCFNumberCGFloatType, &result);
    return result;
}
@end

or using the C11 feature "Generic selection", where the compiler chooses the appropriate code depending on the type of CGFloat :或使用 C11 特性“通用选择”,编译器根据CGFloat的类型选择适当的代码:

@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
    CGFloat result;
    result = _Generic(result,
            double: [self doubleValue],
            float: [self floatValue]);
    return result;
}
@end

And then进而

NSNumber *n = @42.24;
CGFloat f = [n myCGFloatValue];

but I doubt that it is worth the hassle.但我怀疑这是否值得麻烦。

Just always get the double value.总是得到双重价值。 If CGFloat is only a 'float' on your machine the double will be instantly truncated, so you don't care.如果 CGFloat 只是您机器上的“浮点数”,则双精度值将立即被截断,因此您不必在意。

The older answers are both correct.较旧的答案都是正确的。 Just for my 2¢, here's my implementation:只是为了我的 2 美分,这是我的实现:

@implementation NSNumber (TypeConversion)

- (CGFloat)cgFloatValue
{
#if CGFLOAT_IS_DOUBLE
    return self.doubleValue;
#else
    return self.floatValue;
#endif
}

@end

This relies on the definition of CGFLOAT_IS_DOUBLE in CGBase.h for Objective C, or CoreGraphics.h for Swift:这依赖于所述的定义CGFLOAT_IS_DOUBLE在CGBase.h为目标C,或CoreGraphics.h为夫特:

// Don't write this code; it's already included in Foundation :)

#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif

typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1

From CoreGraphics.h来自CoreGraphics.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM