API Smell: NSNumber
NSNumber
’s weakness lies in the ambiguous type of its value. If you receiveNSNumber *aNumber
as a method parameter and want to know its scalar value, what type should it be evaluated as? Is it correct to treat it as aYES
/NO
, and send it[aNumber boolValue]
? Or perhaps it’s a floating-point value and should be sent[aNumber floatValue]
? Without introspecting the Objective-C type encoding of anNSNumber
, a glance at its value doesn’t hint at the original value. Consider anNSNumber
whoseintegerValue
is1
. Is it a signed or unsigned integer? Is it a boolean? Or is it a float that happens to be1.0
?
He recommends:
An objective evaluation of one’s use of
NSNumber
makes for clearer and more future-proof code.NSNumber
should be used only as a temporary representation of a numeric value. If an instance ofNSNumber
has numeric meaning, it should be converted to a scalar value; otherwise, it should be converted to anNSString
.
Also, if you have an API that uses NSNumber
, you should document its type. This is not good:
NSString * const NSURLFileSizeKey; // Total file size in bytes (Read-only, value type NSNumber)
I would have assumed that a file size is an unsigned long long
, but this Apple sample code treats it as a 32-bit signed integer.