Wednesday, July 24, 2013

API Smell: NSNumber

Christopher Bowns:

NSNumber’s weakness lies in the ambiguous type of its value. If you receive NSNumber *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 a YES/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 an NSNumber, a glance at its value doesn’t hint at the original value. Consider an NSNumber whose integerValue is 1. Is it a signed or unsigned integer? Is it a boolean? Or is it a float that happens to be 1.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 of NSNumber has numeric meaning, it should be converted to a scalar value; otherwise, it should be converted to an NSString.

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.

Comments RSS · Twitter

Leave a Comment