Quelle est la pratique la plus courante et la plus correcte pour get un CGFloat à partir d'un NSNumber?

Le code de travail pour moi est quelque chose comme:

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

Il pourrait y avoir aussi

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

Mais ça sent encore plus laid pour moi.

Il me semble qu'il devrait y avoir une meilleure API pour faire une chose si commune. Y a-t-il?

Cela obtiendra le bon résultat dans tous les cas:

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

parce que CGFloat est float ou double .


NSNumber n'a pas de méthode CGFloatValue . Vous pouvez en définir un en utilisant le pont sans frais vers CFNumberRef :

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

ou en utilisant la fonction C11 "Sélection générique", où le compilateur choisit le code approprié en fonction du type de CGFloat :

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

Et alors

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

mais je doute que cela en vaille la peine.

Juste toujours la double valeur. Si CGFloat est seulement un «flotteur» sur votre machine, le double sera instantanément tronqué, donc vous vous en fichez.

Les réponses les plus anciennes sont toutes les deux correctes. Juste pour mes 2 ¢, voici ma mise en œuvre:

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

Cela dépend de la définition de CGFLOAT_IS_DOUBLE dans CGBase.h pour Objective C, ou CoreGraphics.h pour Swift:

 // 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 

De CoreGraphics.h