Search code examples
iosobjective-ccomparensnumber

iOS - Why Does It Work When I Compare Two NSNumbers With "=="?


In my app, I accidentally used "==" when comparing two NSNumber objects like so:

NSNumber *number1;
NSNumber *number2;

Later on, after these objects' int values were set, I accidentally did this:

if (number1 == number2) {
    NSLog(@"THEY'RE EQUAL");
}

And, confusingly, it worked! I could have sworn I was taught to do it this way:

if (number1.intValue == number2.intValue) {
    NSLog(@"THEY'RE EQUAL");
}

How did using "==" between the two NSNumber objects work, and why? Does that mean it's okay to compare them that way, or was it just a fluke and this is generally not guaranteed to work every time? It really confused me :(


Solution

  • That is possibly a fluke.

    From NSHipster :

    Two objects may be equal or equivalent to one another, if they share a common set of observable properties. Yet, those two objects may still be thought to be distinct, each with their own identity. In programming, an object’s identity is tied to its memory address.

    Its possible that your statement evaluated to YES because number1 and number2 were pointing to the same object. This would not work if they had the same value but were two different objects.

    The obvious reason NSNumber variables would point to the same would be that you explicitly assigned one to the other, like so:

    number1 = number2;
    

    But there's one other thing. From this answer :

    This is likely either a compiler optimisation or an implementation detail: as NSNumber is immutable there's no need for them be separate instances. probably an implementation optimisation thinking about it. Likely numberWithInt returns a singleton when called subsequently with the same integer.

    But anyways, its safest to use isEqualToNumber:, as there is no telling what other "things" are lurking in the depths of code that may or may not cause it to evaluate YES

    From RyPress :

    While it’s possible to directly compare NSNumber pointers, the isEqualToNumber: method is a much more robust way to check for equality. It guarantees that two values will compare equal, even if they are stored in different objects.