我的工作代码如下:
NSNumber *n = @42.42;
CGFloat cgf = 0;
CFNumberRef cfn = CFBridgingRetain(n);
CFNumberGetValue(cfn, kCFNumberCGFloatType, &cgf);
CFRelease(cfn);
也可能
CGFloat cgf = (CGFLOAT_IS_DOUBLE) ? [n doubleValue] : [n floatValue];
但这对我来说更加丑陋。
在我看来应该有更好的API来做这样一个普通的事情。有吗?
答案 0 :(得分:12)
在任何情况下都会得到正确的结果:
NSNumber *n = @42.42;
CGFloat cgf = [n doubleValue];
因为CGFloat
是float
或double
。
NSNumber
没有CGFloatValue
方法。你可以定义一个
使用免费桥接到CFNumberRef
:
@interface NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue;
@end
@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
CGFloat result;
CFNumberGetValue((__bridge CFNumberRef)(self), kCFNumberCGFloatType, &result);
return result;
}
@end
或使用C11功能“通用选择”,其中编译器选择适当的选项
代码取决于CGFloat
的类型:
@implementation NSNumber (MyCGFloatValue)
-(CGFloat)myCGFloatValue{
CGFloat result;
result = _Generic(result,
double: [self doubleValue],
float: [self floatValue]);
return result;
}
@end
然后
NSNumber *n = @42.24;
CGFloat f = [n myCGFloatValue];
但我怀疑这是值得的麻烦。
答案 1 :(得分:4)
总是得到双倍价值。如果CGFloat只是你机器上的'浮动',那么双重会立即被截断,所以你不在乎。
答案 2 :(得分:1)
旧答案都是正确的。只是为了我的2美分,这是我的实施:
@implementation NSNumber (TypeConversion)
- (CGFloat)cgFloatValue
{
#if CGFLOAT_IS_DOUBLE
return self.doubleValue;
#else
return self.floatValue;
#endif
}
@end
这依赖于CGBase.h中针对Objective C的CGFLOAT_IS_DOUBLE
的定义,或者针对Swift的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