8

次のコードがあるとします。

int firstInt, secondInt;

firstInt = 5;
secondInt = 5;

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

なぜこれらの 2 つの NSNumber インスタンスが同じアドレスを指しているのですか?

これは私を夢中にさせます!

もちろん、secondInt を「4」などに変更すると、すべてが期待どおりに機能します。

ありがとう、ジェレミー

4

3 に答える 3

12

これは、コンパイラの最適化または実装の詳細のいずれかである可能性があります。NSNumber は不変であるため、それらを個別のインスタンスにする必要はありません。

編集:おそらくそれについて考えている実装の最適化。おそらく numberWithInt は、同じ整数で後で呼び出されたときにシングルトンを返します。

于 2010-11-24T18:16:17.717 に答える
6

私の設計上の本能によると、スコアの ID が単なる値とは異なるものとして重要である場合、単純な NSNumber ではなく何らかの種類のスコア オブジェクトをソートする必要があります。

しかし、それはさておき: ピンチでは、NSNumber の使用方法と同様に、プレーンな NSValue を使用できます。値を取得するのはもう少し手間がかかりますが、NSValue 自体には、NSNumber が小さな値に対して行うインスタンス合体動作がありません。

3 つの動作すべてを実行するコード:

  // 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]);

私のMacでは、これにより次のような出力が得られます。

one: NSConcreteValue 42a8d0 = 5 ; two: NSConcreteValue 42a920 = 5
three: NSCFNumber 404380 = 6 ; four: NSCFNumber 404380 = 6
five: NSCFNumber 1324d0 = 8675309 ; six: NSCFNumber 106e00 = 8675309
于 2010-11-24T19:32:06.493 に答える
3

それらは同じhash値を持っているためNSNumber、最初の割り当てからキャッシュされたポインターが返されます。

于 2010-11-24T18:17:03.457 に答える