चलिए retain
और release
से शुरू करते हैं; एक बार जब आप बुनियादी अवधारणाओं को समझते हैं तो autorelease
वास्तव में केवल एक विशेष मामला है।
कोको में, प्रत्येक ऑब्जेक्ट ट्रैक करता है कि कितनी बार संदर्भित किया जा रहा है (विशेष रूप से, NSObject
बेस क्लास इसे लागू करता है)। किसी ऑब्जेक्ट पर retain
पर कॉल करके, आप यह कह रहे हैं कि आप इसकी संदर्भ गणना एक करके करना चाहते हैं। release
पर कॉल करके, आप उस ऑब्जेक्ट को बताते हैं जिसे आप इसे छोड़ रहे हैं, और इसकी संदर्भ गणना कम हो गई है। यदि, release
पर कॉल करने के बाद, संदर्भ संख्या अब शून्य है, तो उस ऑब्जेक्ट की स्मृति सिस्टम द्वारा मुक्त हो जाती है।
यह malloc
और free
से भिन्न मूल तरीका यह है कि किसी दिए गए ऑब्जेक्ट को सिस्टम के अन्य हिस्सों के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि आपने स्मृति को मुक्त कर दिया है। मान लें कि सभी नियमों के अनुसार खेल रहे हैं और बनाए/जारी कर रहे हैं, जब कोड का एक टुकड़ा बरकरार रहता है और फिर ऑब्जेक्ट को जारी करता है, तो कोड का कोई भी अन्य भाग भी ऑब्जेक्ट का संदर्भ नहीं देगा।
कभी-कभी भ्रमित करने वाला क्या हो सकता है उन परिस्थितियों को जानना जिनके तहत आपको retain
और release
पर कॉल करना चाहिए। अंगूठे का मेरा सामान्य नियम यह है कि यदि मैं कुछ समय के लिए किसी ऑब्जेक्ट पर लटकना चाहता हूं (उदाहरण के लिए, यह वर्ग में सदस्य चर है), तो मुझे यह सुनिश्चित करना होगा कि ऑब्जेक्ट की संदर्भ संख्या मेरे बारे में जानती है। जैसा कि ऊपर वर्णित है, retain
पर कॉल करके ऑब्जेक्ट की संदर्भ गणना बढ़ी है। सम्मेलन के अनुसार, जब वस्तु "init" विधि के साथ बनाई जाती है तो यह भी बढ़ी है (वास्तव में 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 को सुविधाजनक (और कभी-कभी आवश्यक) तरीके के रूप में उपयोग किया जाता है।एक नलसाजी परिप्रेक्ष्य से, जब autorelease
कहा जाता है, वर्तमान धागे के NSAutoreleasePool
को कॉल से सतर्क किया जाता है। NSAutoreleasePool
अब जानता है कि एक बार यह अवसर मिलने के बाद (ईवेंट लूप के वर्तमान पुनरावृत्ति के बाद), यह ऑब्जेक्ट पर release
पर कॉल कर सकता है। प्रोग्रामर के रूप में हमारे परिप्रेक्ष्य से, यह हमारे लिए release
पर कॉल करने का ख्याल रखता है, इसलिए हमें (और वास्तव में, हमें नहीं करना चाहिए)।
यह ध्यान रखना महत्वपूर्ण है कि (फिर से, सम्मेलन द्वारा) सभी ऑब्जेक्ट सृजन कक्षा विधियां एक ऑटोरेलेज्ड ऑब्जेक्ट लौटाती हैं। उदाहरण के लिए, निम्नलिखित उदाहरण में, परिवर्तनीय "एस" की संदर्भ संख्या 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];
}
मुझे पता है यह सब एक सा भ्रामक है - कुछ बिंदु पर है, हालांकि, यह क्लिक करेगा। आपको जाने के लिए यहां कुछ संदर्भ दिए गए हैं:
- Apple's introduction स्मृति प्रबंधन के लिए।
- Cocoa Programming for Mac OS X (4th Edition), हारून हिलेगैस द्वारा - बहुत सारे महान उदाहरणों के साथ एक बहुत अच्छी तरह लिखित पुस्तक। यह एक ट्यूटोरियल की तरह पढ़ता है।
- यदि आप वास्तव में डाइविंग कर रहे हैं, तो आप Big Nerd Ranch पर जा सकते हैं। यह ऊपर वर्णित पुस्तक के लेखक हारून हिलेगलेस द्वारा संचालित एक प्रशिक्षण सुविधा है। मैंने कई साल पहले कोको कोर्स के परिचय में भाग लिया था, और यह सीखने का एक शानदार तरीका था।
आपने लिखा: "autorelease को कॉल करके, हम अस्थायी रूप से संदर्भ गणना को टक्कर देते हैं"। मुझे लगता है कि यह गलत है; ऑटोरेलीज केवल भविष्य में ऑब्जेक्ट को रिलीज़ करने के लिए चिह्नित करता है, यह रेफ गिनती में वृद्धि नहीं करता है: http://cocoadev.com/index.pl?AutoRelease – LKM
"अब ऑटोरेलीज के लिए। Autorelease को सुविधाजनक (और कभी-कभी जरूरी) थोड़ी देर के बाद इस वस्तु को मुक्त करने के लिए सिस्टम को बताने का तरीका। " लीड-इन वाक्य के रूप में, यह गलत है। यह सिस्टम को "मुक्त [इसे] ऊपर" नहीं बताता है, यह इसे बनाए रखने की गिनती को कम करने के लिए कहता है। – mmalc
इसी तरह, आपका अंतिम कोड उदाहरण NSString को कई बार रिलीज़ करता है - एक बार एनएसयूटोरोज़ी पूल में ऑटोरेलीज के माध्यम से और सीधे रिलीज के माध्यम से :( – rpetrich