Sweetened Cocoa: The Number Class

Last week, we presented the String class, which gifts the standard Cocoa NSString class with such modern conveniences as operator overloading, allowing the developer to focus more on clearly expressing the intent of the code, and less on arcane 1980s syntax. Today, we're going to look at another Cocoa class in dire need of some help: NSNumber.

Granted, NSNumber doesn't come up as often in real code as NSString, because, unlike the case with strings, C actually has some decent built-in numeric types. So we generally just use int, double, or maybe CGFloat ivars directly, without bothering with NSNumber, because the latter is such a pain in the neck to use.

Sometimes, however, you do have to use it, since Cocoa container classes (most notably NSDictionary and NSArray) can't contain primitive types, but only things that derive from NSObject. So that means mucking about with NSNumbers.

This is unfortunate, because without any operator overloading, implicit conversion, or destructors to rely on, Objective-C forces you to write code that looks something like this:

    NSNumber *a = [NSNumber numberWithInt:1];
    NSNumber *b = [NSNumber numberWithDouble:2.2];
    NSNumber *sum = [NSNumber numberWithDouble:[a doubleValue] + [b doubleValue]];
    NSNumber *limit = [NSNumber numberWithInt:2];
    assert( [sum compare:limit] >= NSOrderedSame );

And this is in a case where we can rely on the autorelease pool! That's an awful lot of noise syntax for what is actually a very simple set of operations.

I won't bother you with all the implementation details, but with the Number class (see Number.mm and Number.h), you can write the above code as:

    Number a = 1;
    Number b = 2.2;
    Number sum = a + b;
    Number limit(2);
    assert( sum >= limit );

Much clearer, no? And just as String is toll-free bridged to NSString and CFString, our Number class is toll-free bridged to NSNumber. This means that you can assign any NSNumber* you might have (e.g., from an NSArray, or NSUserDefaults, or whatever) directly to a Number reference, or stuff any Number directly into an NSDictionary or what have you.

Basically, Number is just an NSNumber, but with the ability to do math, assignment, and comparisons the way math, assignment, and comparisons ought to be done (i.e., with math, assignment, and comparison operators). Thanks to Apple for giving us Objective-C++ to make all this possible!