2011-09-03 12 views
7

में ऑटोरेलीज बनाम रिलीज मुझे पता है कि आईओएस में मेमोरी मैनेजमेंट मेरे जैसे नए लोगों के लिए मुश्किल है, लेकिन मैं यहां स्टैक ओवरफ्लो पर एक स्पष्ट स्पष्टीकरण की उम्मीद कर रहा था जिसे मैं कहीं और नहीं मिला।dealloc

तो, नाटक मैं एक संपत्ति/इवर

@property(nonatomic, retain) UIPopoverController *popOver; 

जो मैं इस तरह का आवंटन कर रहा हूँ है: मेरे dealloc और viewDidUnload तरीकों में अब

self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease];  

,, मैं दोनों

करना
// in viewDidUnload: 
self.popOver = nil; 
// in dealloc: 
[popOver release]; 

प्रश्न:

  1. यदि मैं देखने में शून्य/रिलीज करता हूं DidUnload/dealloc, क्या मुझे वास्तव में आवंटन पर autorelease करने की आवश्यकता है?
  2. इसके विपरीत, अगर मैं आवंटन पर ऑटोरेलीज करता हूं, तो क्या मुझे बाद में शून्य/रिलीज करने की आवश्यकता है?
  3. क्या अंतर है, यदि कोई है?

अपने समय के लिए अग्रिम धन्यवाद - मुझे पढ़ने जारी रखेंगे, गंभीरता से स्मृति प्रबंधन नहीं किया जा सकता चारों ओर अपने सिर कि हार्ड रैप करने के लिए ...

+0

शीर्षक संपादित करने के लिए धन्यवाद; मैंने इसी तरह के प्रश्न देखे जिनके सामने "आईओएस:" था; वास्तव में इसके बिना शुरू किया। – pille

उत्तर

5

इस पंक्ति में autorelease से भ्रमित नहीं होना है:

self.popOver = [[[UIPopoverController alloc] initWithContentViewController:popOverContent] autorelease]; 

इस बयान के बाद आप प्रभावी रूप से वस्तु ही क्योंकि संपत्ति सेटर इसके बारे में स्वामित्व का दावा किया। Autorelease alloc-init को संतुलित करता है।

तो ... हाँ, आपको आवंटन पर ऑटोरेलीज की आवश्यकता है। आप इस (कोई autorelease) किया था, तो आप का रिसाव करेगा:

self.popOver = [[UIPopoverController alloc] initWithContentViewController:popOverContent]; 

एक अन्य विकल्प autorelease के बजाय एक अस्थायी चर का उपयोग करने के लिए है:

UIPopoverController *temp = [[UIPopoverController alloc] initWithContentViewController:popOverContent]; 
self.popOver = temp; 
[temp release]; 

किसी भी तरह से आप dealloc में वस्तु को रिहा करने की जरूरत है।

+0

अबीज़र्न और यूजी के लिए उनके बहुत ही प्रबुद्ध उत्तरों के लिए धन्यवाद। अब भी मैं यूजी के जवाब में वर्णित "स्थानीय स्वामित्व" के विचार को समझ गया। किसी भी तरह, क्या स्मृति अनुप्रयोगों (शायद उपकरण का उपयोग कर) के लिए आपके आवेदन का परीक्षण करने का कोई तरीका है? – pille

+0

@ फिल हाँ, आप [इंस्ट्रूमेंट्स] (http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Introduction/Introduction.html) का उपयोग कर सकते हैं। एक्सकोड में, [रन बटन पर क्लिक करके रखें] (http://stackoverflow.com/questions/5305906/xcode-4-running-the-leaks-instrument) या [उत्पाद -> प्रोफ़ाइल] चुनें (http: // stackoverflow .com/प्रश्न/5304390/उपकरणों में xcode -4)। यह एक संवाद लाता है जहां आप "लीक" चुन सकते हैं। – albertamg

+0

@pille इंस्ट्रूमेंट्स का उपयोग करने से पहले, बस "विश्लेषण करें", जो एक्सकोड के "बिल्ड" मेनू के नीचे उपलब्ध है। – Yuji

4

1 मैं में नहीं के बराबर/रिलीज करते हैं viewDidUnload/dealloc, क्या मुझे वास्तव में आवंटन पर autorelease करने की आवश्यकता है?

हां।

2 इसके विपरीत, अगर मैं आवंटन पर autorelease करता हूं, तो मुझे बाद में शून्य/रिलीज करने की आवश्यकता है?

हां।

पहले मामले में, स्वत: रिलीज उस विधि की ओर से किया गया है। उस विधि को अब पॉपओवर की आवश्यकता नहीं है, इसलिए इसे (ऑटो) रिलीज़ करने की आवश्यकता है।

dealloc पर, आपके ऑब्जेक्ट को अब पॉपओवर की आवश्यकता नहीं है। इसलिए, आपको इसे जारी करने की आवश्यकता है।

यह बहुत आसान है। आपको दीर्घकालिक वस्तु स्वामित्व पर विचार करने की आवश्यकता नहीं है; आपको बस हर विधि के स्तर पर, स्थानीय रूप से सोचने की जरूरत है। इसे जारी करने का निर्णय या नहीं, इस बात पर निर्भर करता है कि उस वस्तु को कार्यक्रम के कुछ अन्य हिस्सों द्वारा रखा गया है या नहीं। एक विधि में, यदि आप किसी ऑब्जेक्ट को आवंटित करते हैं और आपको उस विधि में इसकी आवश्यकता नहीं है, तो आप इसे (ऑटो) रिलीज़ करते हैं।

dealloc नियम के लिए थोड़ा अपवाद है। वहां, आपको सभी इंस्टेंस चर के स्वामित्व को रिलीज़ करने की आवश्यकता है।

यही है!

1
  1. हां। लेकिन शायद इस मामले में नहीं।
  2. हां। लेकिन शायद इस मामले में नहीं।
  3. viewDidUnload को तब दृश्य कहा जाता है जब दृश्य अनलोड किया जाता है, dealloc को कॉल कंट्रोलर नष्ट होने पर बुलाया जाता है।

viewDidUnload में आप वस्तुओं है कि अब कोई आवश्यकता नहीं कर रहे हैं और viewDidLoad में निर्मित किया जा सकता है दृश्य द्वारा उपयोग किया जाता छोड़ें। स्पष्ट, चूंकि दृश्य प्रदर्शित नहीं किया जा रहा है, इसलिए इसके लिए दृश्य नियंत्रक द्वारा स्थापित वस्तुओं को पकड़ने की आवश्यकता नहीं है।

dealloc में आप व्यू कंट्रोलर की सफाई कर रहे हैं और यहां आप अपने सभी संसाधनों को साफ़ कर चुके हैं, जिनमें उन्होंने दृश्य को असाइन किया है।

इस मामले में, दृश्य में पॉपओवर नियंत्रक का स्वामित्व नहीं है - इसे व्यू कंट्रोलर के स्वामित्व में होना चाहिए, इसलिए इसे viewDidUnload में रिलीज़ करने की आवश्यकता नहीं है लेकिन आपको इसे dealloc में रिलीज़ करने की आवश्यकता है।

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