从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];
因为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
或使用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