2010-11-24 8 views
7

निम्नलिखित कोड को देखते हुए:मूल्य के बराबर होने पर NSNumber एक ही पते पर क्यों इंगित करता है?

int firstInt, secondInt; 

firstInt = 5; 
secondInt = 5; 

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

पृथ्वी पर क्यों दो एनएसएनंबर उदाहरण एक ही पते पर इंगित कर रहे हैं?

यह मुझे पागल बनाता है!

बेशक, यदि आप दूसरे को बदलते हैं, तो '4' कहें, सभी काम अपेक्षित हैं।

धन्यवाद, जेरेमी

+3

आपको क्यों ध्यान अगर वे एक ही वस्तु बनाम साथ दो अलग-अलग वस्तुओं रहे हैं एक ही मूल्य? –

+0

क्योंकि वे एक ही मूल्य साझा करते हैं, फिर भी मुझे स्कोर की गणना करने के लिए अलग-अलग उदाहरण होने की आवश्यकता होती है। – jchatard

उत्तर

12

यह संभावना है या तो एक संकलक अनुकूलन या एक कार्यान्वयन विस्तार: के रूप में NSNumber अपरिवर्तनीय है कोई जरूरत उन्हें अलग उदाहरण हो के लिए नहीं है।

संपादित करें: शायद इसके बारे में सोचने के लिए एक कार्यान्वयन अनुकूलन। संभावित संख्या के साथ बाद में एक ही पूर्णांक के साथ बुलाए जाने पर एक सिंगलटन लौटाता है।

+2

आईआईआरसी एनएस नम्बर में एक आंतरिक अनुकूलन है जो निचले पूर्णांक के लिए सिंगलेट्स देता है। व्यवहार में इससे कोई फर्क नहीं पड़ता क्योंकि यह वह मूल्य है जो महत्वपूर्ण है और स्मृति पता नहीं है। – Abizern

+7

+1 0-12 के लिए 'NSNumbers' सिंगलेट हैं। –

+0

मेरी समस्या यह है कि मुझे उन int को सरणी में जोड़ने की आवश्यकता है, उन्हें क्रमबद्ध करें (उनके मूल्य से) और अपनी अनुक्रमणिका (सरणी के अंदर) पुनर्प्राप्त करें। और सिंगलटन की वजह से, मुझे गलत इंडेक्स मिलता है। – jchatard

3

क्योंकि उनके पास hash मान है, इसलिए NSNumber आपको पहले आवंटन से एक कैश पॉइंटर देता है।

+0

ठीक है इसे मिला! धन्यवाद – jchatard

6

मेरा डिज़ाइन वृत्ति मुझे बताती है कि, यदि स्कोर की पहचान अपने मूल्य से अलग है, तो आपको सादे NSNumbers के बजाय किसी प्रकार की स्कोर ऑब्जेक्ट को सॉर्ट करना चाहिए।

लेकिन एक तरफ: एक चुटकी में, आप एनएसएनएएलयू का उपयोग कर रहे हैं, इस तरह आप सादे NSValue का उपयोग कर सकते हैं। मूल्यों को प्राप्त करने के लिए यह थोड़ा और काम है, लेकिन NSValue के पास उदाहरण नहीं है कि एनएसएनंबर छोटे मूल्यों के लिए सहकारी व्यवहार करता है।

कुछ कोड है कि सभी तीन व्यवहार अभ्यास:

// 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 
+0

वाह उत्कृष्ट! बहुत बहुत धन्यवाद, जो वास्तव में मदद करता है। – jchatard

+0

ऐसा लगता है कि वर्षों में बड़ी संख्या में स्टोर करने के लिए कार्यान्वयन में सुधार हुआ है।स्निपेट 'NSNumber * पांच = [NSNumber संख्या WithInt: 8675309] के लिए; एनएसएनंबर * छः = [एनएसएनंबर संख्या विथेंट: 867530 9]; एनएसएलओजी (@ "पांच:% @% x =% d; छः:% @% x =% d", [पांच वर्ग], पांच, [पांच intValue], [छः वर्ग], छः, [छः intValue ]); ' \t मुझे एक ही पते के साथ आउटपुट मिलता है:' पांच: __NSCFNumber 845fed27 = 8675309; छः: __NSCFNumber 845fed27 = 8675309' –

+0

मुझे लगता है कि 64-बिट वातावरण के साथ आया "टैग पॉइंटर्स" के कारण: https://www.mikeash.com/pyblog/friday-qa-2012-07-27-lets -बिल्ड-टैग-पॉइंटर्स.html। टीएलडीआर: टैगिंग ओवरहेड से 64 बिट्स से कम कोई भी एनएसएनंबर, अब "सिंगलटन इंस्टेंस" हो सकता है (जो वास्तव में केवल पॉइंटर वैल्यू है।) [ध्यान दें कि आपका पॉइंटर वैल्यू एक अजीब संख्या है, जो सही पॉइंटर्स नहीं हो सकते ] – rgeorge

संबंधित मुद्दे