代码之家  ›  专栏  ›  技术社区  ›  jchatard

当值等于时,为什么NSNumber指向同一地址?

  •  7
  • jchatard  · 技术社区  · 15 年前

    给定以下代码:

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

    为什么这两个NSNumber实例指向同一个地址?

    这把我逼疯了!

    当然,如果您将secondInt改为,比如说'4',所有操作都会按预期进行。

    谢谢, Jrmy公司

    3 回复  |  直到 15 年前
        1
  •  12
  •   Tim    15 年前

    这可能是编译器优化或实现细节:由于NSNumber是不可变的,所以它们不需要是单独的实例。

    编辑:可能是一个正在考虑的实现优化。当随后使用相同整数调用时,可能numberWithInt返回一个singleton。

        2
  •  6
  •   rgeorge    15 年前

    我的设计直觉告诉我,如果分数的标识和它的值一样重要,你应该对某种分数对象进行排序,而不是简单的NSNumbers。

    但是 另外:在紧要关头,您可以使用与使用NSNumber类似的普通NSValue。要得到值需要做更多的工作,但是NSValue本身没有NSNumber对小值所做的实例合并行为。

    一些练习所有三种行为的代码:

      // 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
    
        3
  •  3
  •   Jacob Relkin    15 年前

    因为他们有相同的 hash 价值,所以 NSNumber 从第一个分配返回一个缓存指针。