2010-11-24 71 views
7

考慮下面的代碼:當值相等時,爲什麼NSNumber指向相同的地址?

int firstInt, secondInt; 

firstInt = 5; 
secondInt = 5; 

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

爲什麼在地球上做的這兩個NSNumber的實例都指向同一個地址?

這讓我瘋狂!

當然,如果您將secondInt更改爲「4」,則所有按預期工作。

感謝, 傑里米

+3

你爲什麼關心,如果他們是同一個對象對與兩個不同的對象相同的價值? – 2010-11-24 18:15:40

+0

因爲即使它們具有相同的值,我也需要它們作爲單獨的實例來計算分數。 – jchatard 2010-11-24 18:33:29

回答

12

這可能是或編譯器優化或實現的細節:如NSNumber的是不可變的沒有必要爲他們單獨的實例。

編輯:可能是一個實現優化思考它。當隨後用相同的整數調用時,numberWithInt可能返回一個單例。

+2

IIRC NSNumber有一個內部優化,可以爲較低的整數返回單身人士。在實踐中它應該不重要,因爲它是重要的價值而不是內存地址。 – Abizern 2010-11-24 18:19:33

+7

+1 0-12的`NSNumbers`是單身人士。 – 2010-11-24 18:41:43

3

由於它們具有相同的hash值,因此NSNumber會給您一個來自第一個分配的緩存指針。

6

我的設計本能告訴我,如果得分的身份與其單純的價值不同,那麼應該排序某種得分對象而不是普通的NSNumbers。

但是那邊:在一個捏,你可以使用普通的NSValue類似於你如何使用NSNumber。獲取值需要多一點工作,但是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 
相關問題