API Smell: NSNumber
NSNumber’s weakness lies in the ambiguous type of its value. If you receiveNSNumber *aNumberas 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 anNSNumberwhoseintegerValueis1. 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
NSNumbermakes for clearer and more future-proof code.NSNumbershould be used only as a temporary representation of a numeric value. If an instance ofNSNumberhas 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.