Why NSNumber points to the same address when value are equals?

拜拜、爱过 提交于 2019-11-27 05:53:02

问题


Given the following code:

int firstInt, secondInt;

firstInt = 5;
secondInt = 5;

NSNumber *firstNumber = [NSNumber numberWithInt:firstInt];
NSNumber *secondNumber = [NSNumber numberWithInt:secondInt];

Why on Earth do those two NSNumber instances are pointing to the same address?

This drives me crazy!

Of course, if you change secondInt to, say '4', all works as expected.

Thanks, Jérémy


回答1:


This is likely either a compiler optimisation or an implementation detail: as NSNumber is immutable there's no need for them be separate instances.

EDIT: probably an implementation optimisation thinking about it. Likely numberWithInt returns a singleton when called subsequently with the same integer.




回答2:


My design instinct tells me that, if the score's identity is important as distinct from its mere value, you should be sorting some kind of score object instead of plain NSNumbers.

But that aside: In a pinch, you can use plain NSValue similarly to how you're using NSNumber. It's a little more work to get values out, but NSValue itself doesn't have the instance coalescing behavior NSNumber does for small values.

Some code that exercises all three behaviors:

  // NSValues are always distinct:
  int foo = 5, bar = 5, outfoo, outbar;
  NSValue *one = [NSValue value:&foo withObjCType:@encode(int)];
  NSValue *two = [NSValue value:&bar withObjCType:@encode(int)];

  [one getValue:&outfoo];
  [two getValue:&outbar];
  NSLog(@"one: %@ %x = %d ; two: %@ %x = %d",
        [one class], one, outfoo,
        [two class], two, outbar);

  // by comparison with NSNumber behavior:
  NSNumber *three = [NSNumber numberWithInt:6];
  NSNumber *four = [NSNumber numberWithInt:6];

  NSLog(@"three: %@ %x = %d ; four: %@ %x = %d",
        [three class], three, [three intValue],
        [four class], four, [four intValue]);

  // except when the numbers are big:
  NSNumber *five = [NSNumber numberWithInt:8675309];
  NSNumber *six = [NSNumber numberWithInt:8675309];

  NSLog(@"five: %@ %x = %d ; six: %@ %x = %d",
        [five class], five, [five intValue],
        [six class], six, [six intValue]);

On my mac this yields output like:

one: NSConcreteValue 42a8d0 = 5 ; two: NSConcreteValue 42a920 = 5
three: NSCFNumber 404380 = 6 ; four: NSCFNumber 404380 = 6
five: NSCFNumber 1324d0 = 8675309 ; six: NSCFNumber 106e00 = 8675309



回答3:


Because they have the same hash value, so NSNumber gives back to you a cached pointer from the first allocation.



来源:https://stackoverflow.com/questions/4270121/why-nsnumber-points-to-the-same-address-when-value-are-equals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!