2009-11-26 15 views
5

नीचे दिया गया कोड संकलित और चलाता है, लेकिन सभी आईफोन विकास पुस्तकों और ऐप्पल दस्तावेज के अनुसार यह नहीं होना चाहिए! क्या कोई मुझे बता सकता है कि अपरिवर्तनीय एनएसएसटींग कैसे सेट हो जाने के बाद अपने मूल्यों को बदलने की अनुमति देता है? मैंने सोचा कि मुझे उसी स्ट्रिंग चर के संदर्भ को बदलने के लिए एनएसएमयूटेबलस्ट्रिंग का उपयोग करना था? मैं एसडीके 3.1 का उपयोग कर रहा हूँ।एनएसएसटींग अपरिवर्तनीय अपने मूल्यों को बदलने की अनुमति देता है?

NSString *test =[[NSString alloc] initWithString:@"TEST"]; 
[test release]; 
test = @"TEST2"; 

उत्तर

20

शायद निम्न उदाहरण मार्क और नील्स के उत्तरों पर जोड़ देगा और चीजों को स्पष्ट करने में मदद करेगा।

अपरिवर्तनीय तार

// Setup two variables to point to the same string 
NSString * str1 = @"Hello World"; 
NSString * str2 = str1; 

// "Replace" the second string 
str2 = @"Hello ikilimnik"; 

// And list their current values 
NSLog(@"str1 = %@, str2 = %@", str1, str2); 

परिवर्त्य तार

// Setup two variables to point to the same string 
NSMutableString * str1 = [NSMutableString stringWithString:@"Hello World"]; 
NSMutableString * str2 = str1; 

// "Replace" the second string 
[str2 setString:@"Hello ikilimnik"]; 

// And list their current values 
NSLog(@"str1 = %@, str2 = %@", str1, str2); 

सूचना जब आप अपरिवर्तनीय NSString वर्ग एक ही रास्ता के लिए एक स्ट्रिंग "की जगह" एक नया स्ट्रिंग बनाने और अपनी चर का अद्यतन करने के लिए है कि का उपयोग इसे इंगित करने के लिए "str2"। हालांकि यह "str1" को इंगित नहीं कर रहा है, इसलिए यह मूल स्ट्रिंग का संदर्भ देगा।

एनएसएमयूटेबल स्ट्रिंग उदाहरण में, हम दूसरी स्ट्रिंग नहीं बनाते हैं, बल्कि मौजूदा "हैलो वर्ल्ड" स्ट्रिंग की सामग्री को बदलते हैं (mutate)। चूंकि दोनों चर एक ही स्ट्रिंग ऑब्जेक्ट को इंगित करते रहते हैं, इसलिए वे दोनों एनएसएलओजी को कॉल में नए मान की रिपोर्ट करेंगे।

पॉइंटर चर और वास्तविक ऑब्जेक्ट के बीच अंतर करना महत्वपूर्ण है। एक एनएसएसटींग ऑब्जेक्ट अपरिवर्तनीय है, लेकिन यह आपको एक चर के मान को बदलने से नहीं रोकता है जो स्ट्रिंग को इंगित करता है।

डेटा प्रकार "एनएसएसटींग *" एक एनएसएसटींग ऑब्जेक्ट के लिए एक सूचक है, ऑब्जेक्ट स्वयं नहीं। यदि आप XCode डीबगर के भीतर किसी भी NSLog कथन में ब्रेक पॉइंट सेट करते हैं, तो आप इसे स्पष्ट करने के लिए प्रत्येक चर के कच्चे मान को देखना चाहेंगे।

+1

+1 वास्तव में व्याख्या करने के लिए और सिर्फ जवाब देने के लिए नहीं ... –

+1

क्रिस्टोफर धन्यवाद, लेकिन उदाहरण के बारे में इस बारे में क्या: एनएसएसटींग * str = @ "one"; str = [str stringByAppendingString: @ "two"]; क्या आप कह रहे हैं कि भले ही मैं एक ही चर का उपयोग कर रहा हूं, मैं दो अलग-अलग ऑब्जेक्ट्स बना रहा हूं? साथ ही इन एनएसएसटींग ऑब्जेक्ट्स के साथ क्या होता है जो हम स्पष्ट रूप से बनाते हैं, क्या वे autorelease द्वारा साफ हो जाते हैं? –

+1

हां जो दो अपरिवर्तनीय स्ट्रिंग ऑब्जेक्ट्स बनाएगा। "एक" और "onetwo"। Mutable s के लाभों में से एक ट्रिंग्स वे अतिरिक्त अस्थायी स्ट्रिंग ऑब्जेक्ट्स से बचने में मदद कर सकते हैं यदि आप प्रदान किए गए उदाहरण जैसे स्टाइल ऑपरेशंस को बहुत अधिक स्ट्रिंग करते हैं। यह गति और स्मृति उपयोग दक्षता लाभ प्रदान कर सकते हैं। –

7

आप स्ट्रिंग को म्यूट नहीं कर रहे हैं, तो आप एक अलग स्ट्रिंग को इंगित करने के लिए चर परीक्षण को पुन: असाइन कर रहे हैं। मूल स्ट्रिंग को संशोधित नहीं किया गया है।

+0

ठीक है, समझ में आता है। तो ओबीजे सी में स्ट्रिंग्स को म्यूट करके उनका क्या मतलब है? और एनएसएसटींग को नए मान निर्दिष्ट करते समय वे हर पुस्तक में नई स्ट्रिंग बनाने के लिए क्यों कहते हैं? धन्यवाद! –

+2

उनका मतलब है कि एक स्ट्रिंग के अलग-अलग अक्षर बदलना, उदाहरण के लिए "हेलो, दुनिया!" को "येलो, दुनिया!" में बदलना, पहले वर्ण को "वाई" में बदलकर और शेष अपरिवर्तित छोड़कर। इस तरह का ऑपरेशन केवल तभी संभव है जब यह ऑपरेशन केवल तभी संभव हो स्ट्रिंग्स म्यूटेबल हैं, क्योंकि वे सी में हैं, उदाहरण के लिए –

7

टेस्ट और टेस्ट 2 * टेस्ट पॉइंटर द्वारा इंगित दो अलग-अलग तार हैं।

आप स्पष्ट रूप से आवंटित एनएसएसटींग ऑब्जेक्ट की सामग्री को कोड की पहली पंक्ति से नहीं बदल रहे हैं लेकिन किसी अन्य ऑब्जेक्ट को * परीक्षण को इंगित कर रहे हैं।