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

我的工作代码是这样的:

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。 有没有?

无论如何这将得到正确的结果:

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

因为CGFloatfloatdouble


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 

或使用C11function“通用select”,其中编译器根据CGFloat的typesselect适当的代码:

 @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]; 

但我怀疑这是值得的麻烦。

总是得到双重价值。 如果CGFloat在你的机器上只是一个“浮动”,那么double就会被立即截断,所以你不在乎。

旧的答案都是正确的。 只是为了2¢,这是我的实现:

 @implementation NSNumber (TypeConversion) - (CGFloat)cgFloatValue { #if CGFLOAT_IS_DOUBLE return self.doubleValue; #else return self.floatValue; #endif } @end 

这依赖于Objective C中的CGFLOAT_IS_DOUBLE中的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 

从CoreGraphics.h