Compare NSNumber with NSInteger

djibouti33 picture djibouti33 · Mar 24, 2011 · Viewed 10.1k times · Source

I spent some time today chasing down two bugs, and ended up fixing both of them using the same solution.

Now that I have the solution, I was hoping to get some clarity behind it.

I'm comparing an attribute from Core Data (Integer 16/NSNumber) with an Integer (ABPropertyID & ABMultiValueIdentifier).

The bug was in this comparison, and oddly enough, only showed itself after I had killed the app (from the background tray), reopened it, and run through the same process that included the comparison. Anyways...

This is what stopped working after a restart:

if (myNumber.aProperty == [NSNUmber numberWithInt:anInteger]) { /* do stuff here */ }

And these are the two solutions, which so far, are working perfectly:

if ([myNumber.aProperty integerValue] == anInteger) {/* do stuff here */ }

if ([myNumber.aProperty isEqualToNumber:[NSNumber numberWithInt:anInteger]]) { /* do stuff here */ }

To me, they all look identical. I'm always either converting the NSNumber to an integerValue, or converting the integer to an NSNumber.

Any ideas?

Answer

BoltClock picture BoltClock · Mar 24, 2011

Do not use == to compare NSNumbers. Most of the time you'll be comparing two distinct objects, so the comparison won't evaluate to true. If you look at your if condition, notice that you're particularly comparing your property to a brand new NSNumber object.

Since NSInteger is a Cocoa wrapper for certain value types, comparing NSIntegers with == works fine.

The implementation of isEqualToNumber: probably takes the wrapped value types and compares them too.