Question

I really like the new literals in Objective-C. I am wondering if with the new additions there's a better way to compare numbers.

For example, if I want to compare a and b:

a = @1;
b = @2;

Is the only way to compare them like this:

[a intValue] > [b intValue]

Or are there better, more elegant, solutions?

Was it helpful?

Solution

For equality checks, you can use isEqualToNumber which checks if either the id or content is equal (with the latter using compare):

if ([a isEqualToNumber:b])                  // if a == b

Not sure why they also didn't implement isGreaterThanNumber and isLessThanNumber convenience methods (and possibly >= and <= as well), since the compare method below seems a little clunky.

For inequality checks, just use compare directly (you can also do this for equality as can be seen from the first one below):

if ([a compare:b] == NSOrderedSame)         // if (a == b)
if ([a compare:b] == NSOrderedAscending)    // if (a <  b)
if ([a compare:b] == NSOrderedDescending)   // if (a >  b)

if ([a compare:b] != NSOrderedSame)         // if (a != b)
if ([a compare:b] != NSOrderedAscending)    // if (a >= b)
if ([a compare:b] != NSOrderedSescending)   // if (a <= b)

Details can be found on the NSNumber class documentation page.


Keep in mind there's nothing preventing you from creating your own helper function which would, for example, allow code like:

if (nsnComp1 (a, ">=", b)) ... // returns true/false (yes/no)

or:

if (nsnComp2 (a, b) >= 0)  ... // returns -1/0/+1

even though it's less Objective-C and more C :-) It depends on whether your definition of "elegant" is bound mostly by efficiency or readability. Whether that's preferable to your intValue option is a decision you'll need to make yourself.

OTHER TIPS

NSNumber implements -compare: (as do a number of other classes). So you can say

switch ([a compare:b]) {
    case NSOrderedAscending: // a < b
        // blah blah
        break;
    case NSOrderedSame: // a == b
        // blah blah
        break;
    case NSOrderedDescending: // a > b
        // blah blah
        break;
}

NSNumber also has an isEqualToNumber:

Here is the code snippet to check which works good:

NSLog(@"%d", number1 == number2);
NSLog(@"%d", [number1 isEqual:number2]);
NSLog(@"%d", [number1 isEqualToNumber:number2]);

The output:

1
1
1

Conclusion:

To understand comparison, you need to understand instance allocation. NSNumber internally implements a cache of objects assigned, and maps existing objects to any newly created objects using values. If an existing NSNumber object is found holding value 1, no new NSNumber instance is created.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top