चलो शुरू करते हैं retainऔर release; autoreleaseमूल अवधारणाओं को समझने के बाद वास्तव में सिर्फ एक विशेष मामला है।
कोको में, प्रत्येक वस्तु इस बात का ट्रैक रखती है कि उसे कितनी बार संदर्भित किया जा रहा है (विशेषकर, NSObjectबेस क्लास इसे लागू करता है)। retainकिसी ऑब्जेक्ट पर कॉल करके , आप यह बता रहे हैं कि आप इसकी संदर्भ संख्या एक से बढ़ाना चाहते हैं। कॉल करके release, आप उस ऑब्जेक्ट को बताते हैं जिसे आप इसे जाने दे रहे हैं, और इसकी संदर्भ संख्या को घटाया गया है। यदि, कॉल करने के बाद release, संदर्भ गणना अब शून्य है, तो उस ऑब्जेक्ट की मेमोरी सिस्टम द्वारा मुक्त हो जाती है।
मूल तरीका इससे भिन्न होता है mallocऔर freeयह है कि किसी भी दिए गए ऑब्जेक्ट को सिस्टम के अन्य हिस्सों के दुर्घटनाग्रस्त होने के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि आपने उपयोग की गई मेमोरी को मुक्त कर दिया है। यह मानते हुए कि हर कोई नियमों के अनुसार खेल रहा है और बनाए रख रहा है / जारी कर रहा है, जब कोड का एक टुकड़ा बनाए रखता है और फिर ऑब्जेक्ट को रिलीज़ करता है, तो कोड का कोई अन्य टुकड़ा भी संदर्भित करता है और ऑब्जेक्ट अप्रभावित रहेगा।
जो कभी-कभी भ्रमित हो सकता है वह उन परिस्थितियों को जान रहा है जिनके तहत आपको कॉल करना चाहिए retainऔर release। मेरे अंगूठे का सामान्य नियम यह है कि अगर मैं किसी वस्तु को कुछ समय के लिए लटकाना चाहता हूं (यदि यह किसी वर्ग में सदस्य चर है, उदाहरण के लिए), तो मुझे यह सुनिश्चित करने की आवश्यकता है कि वस्तु का संदर्भ गणना मेरे बारे में जानता है। जैसा कि ऊपर वर्णित है, किसी ऑब्जेक्ट की संदर्भ गणना को कॉल करके बढ़ाया जाता है retain। कन्वेंशन द्वारा, यह भी बढ़े हुए (1, वास्तव में) सेट किया जाता है, जब ऑब्जेक्ट "इनिट" विधि के साथ बनाया जाता है। इन मामलों में से किसी में, releaseजब मैं इसके साथ किया जाता है, तो वस्तु पर कॉल करना मेरी जिम्मेदारी है। अगर मैं नहीं करता हूं, तो स्मृति रिसाव होगा।
वस्तु निर्माण का उदाहरण:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
अब के लिए autorelease। ऑटोरेलेज़ का उपयोग एक सुविधाजनक (और कभी-कभी आवश्यक) तरीके के रूप में किया जाता है ताकि इस वस्तु को थोड़ी देर बाद मुक्त किया जा सके। एक नलसाजी दृष्टिकोण से, जब autoreleaseकहा जाता है, तो वर्तमान थ्रेड NSAutoreleasePoolको कॉल के बारे में सतर्क किया जाता है। NSAutoreleasePoolअब कोई जानता है कि एक बार यह एक अवसर (घटना पाश की वर्तमान यात्रा के बाद) हो जाता है, यह कॉल कर सकते हैं releaseवस्तु पर। प्रोग्रामर के रूप में हमारे दृष्टिकोण से, यह releaseहमारे लिए कॉल करने का ख्याल रखता है, इसलिए हमें (और वास्तव में, हमें नहीं करना चाहिए)।
यह ध्यान रखना महत्वपूर्ण है कि (फिर, सम्मेलन द्वारा) सभी ऑब्जेक्ट निर्माण वर्ग विधियाँ एक ऑटोरेल्ड ऑब्जेक्ट लौटाती हैं। उदाहरण के लिए, निम्नलिखित उदाहरण में, चर "s" में 1 की संदर्भ संख्या है, लेकिन इवेंट लूप के पूरा होने के बाद, यह नष्ट हो जाएगा।
NSString* s = [NSString stringWithString:@"Hello World"];
यदि आप उस स्ट्रिंग को लटकाना चाहते हैं, तो आपको retainस्पष्ट रूप से कॉल करने की आवश्यकता होगी , और releaseजब आप काम कर रहे हों तब इसे स्पष्ट रूप से करें ।
निम्नलिखित कोड पर विचार करें (बहुत अधिक वंचित), और आपको एक ऐसी स्थिति दिखाई देगी, जहां autoreleaseआवश्यक है:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:@"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
मुझे लगता है कि यह सब थोड़ा भ्रमित करने वाला है - कुछ बिंदु पर, हालांकि, यह क्लिक करेगा। यहां आपको जाने के लिए कुछ संदर्भ दिए गए हैं:
- स्मृति प्रबंधन के लिए एप्पल का परिचय ।
- मैक ओएस एक्स (4 वें संस्करण) के लिए कोको प्रोग्रामिंग , आरोन हिलेगास द्वारा - बहुत अच्छे उदाहरणों के साथ एक बहुत अच्छी तरह से लिखित पुस्तक। यह एक ट्यूटोरियल की तरह पढ़ता है।
- यदि आप वास्तव में डाइविंग कर रहे हैं, तो आप बिग नर्ड रेंच पर जा सकते हैं । यह एक प्रशिक्षण सुविधा है जिसे आरोन हिल्गास द्वारा चलाया जाता है - ऊपर वर्णित पुस्तक के लेखक। मैंने कई साल पहले वहाँ कोको कोर्स में इंट्रो में भाग लिया था, और यह सीखने का एक शानदार तरीका था।