Handling CGFloat with an NSScanner on arm64

arm64, cgfloat, cocoa-touch, double, nsscanner

Solution

`NSScanner` only supports a few basic types, so you're going to need to have that #if directive somewhere. That said, if you're using this often you could subclass NSScanner or use a category to make the code more elegant.

I think the category-based code would look something like:

NSScanner+MyAdditions.h:

#import "NSScanner.h"

@interface NSScanner (MyAdditions)
  - (BOOL)my_scanCGFloat:(CGFloat *) cgFloatValue
@end

NSScanner+MyAdditions.m:

#import "NSScanner+MyAdditions.h"

@implementation NSScanner (MyAdditions)
  - (BOOL)my_scanCGFloat:(CGFloat *) cgFloatValue {
#if CGFLOAT_IS_DOUBLE 
    return [self scanDouble:cgFloatValue]; 
#else 
    return [self scanFloat:cgFloatValue]; 
#endif
}
@end

Problem

Apparently `CGFloat` is `double` on arm64: ``` #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 ``` So the code ``` NSScanner *scanner = [NSScanner scannerWithString:string]; CGFloat c[components]; [scanner scanFloat:&c[i]] ``` which was working fine for 32-bit apps, is broken for 64-bit. It can be replaced with ``` NSScanner *scanner = [NSScanner scannerWithString:string]; CGFloat c[components]; #if CGFLOAT_IS_DOUBLE [scanner scanDouble:&c[i]]; #else [scanner scanFloat:&c[i]]; #endif ``` But is there a better alternative?

Original source