2009-04-30 4 views
7

कहीं मुझे लगता है कि पढ़ रहा था - कम स्मृति चेतावनी के बारे में और सभी यह subviews के साथ एक गैर दृश्य दृश्य (= एक पूरी निब, मुझे लगता है) को देने, आप ऐसा करना चाहिए:मुझे क्यों लिखना चाहिए [anView रिलीज], anView = nil; [anView रिलीज] के बजाय ;?

-(void)dealloc { 
    [anView release], anView = nil; 
    [someImageView release], someImageView = nil; 

    [super dealloc]; 
} 
बजाय

-(void)dealloc { 
    [anView release]; 
    [someImageView release]; 

    [super dealloc]; 
} 

रिलीज कॉल करने के बाद उन पॉइंटर्स को शून्य (= "कोई ऑब्जेक्ट") ग्राउंड करने का कारण क्या है? मुझे लगता है: कुछ अन्य तरीकों से कुछ कारणों के लिए दृश्य को देखा जा सकता है (किसी के लिए यह कोई उदाहरण हो सकता है?), तो didReceiveMemory चेतावनी की बात होती है, और आप एक संपूर्ण nib + दृश्य जारी करते हैं जो वर्तमान में दिखाई नहीं दे रहा है (यानी एक मल्टीव्यू-ऐप में)। जैसे ही उपयोगकर्ता फिर से उस दृश्य को देखना चाहता है, आप फिर से निब को लोड करेंगे और फिर: यह सभी विचारों को लोड करता है, आउटलेट को जोड़ता है, और बैंग! आपके अन्य बनाए गए दृश्य अब मेमोरी ईंट में कहीं अकेले किसी भी पॉइंटर के बिना लटक रहे हैं, जिससे आपका ऐप दुर्घटनाग्रस्त होने तक वसा और गहरी मेमोरी लीक हो जाती है।

सही/गलत?

उत्तर

1

बल्कि expicit रिलीज कर की तुलना में और, शून्य करने के लिए सेट करता है, तो अपने accessors yoc उनसे जुड़े गुण होते हैं और अधिक संक्षिप्त तरीके के रूप में निम्न कार्य करें:

- (void) dealloc 
{ 
    self.retainedProperty1 = nil; 
    self.retainedProperty2 = nil; 
    self.copiedProperty = nil; 
    self.assignedProperty = nil; 
} 

इस तरह से आप कोड हो सकता है कम है संश्लेषित कोड के बाद से दोहराव आपके लिए आपके रिलीज का ख्याल रखेगा।

संपादित करें: मैं कहना चाहिए कि आपके गुण केवल पढ़ने के लिए नहीं किया जा सकता वरना आप स्पष्ट कारणों :)

+5

नहीं। यह स्पष्ट रूप से * एप्पल द्वारा निषिद्ध है, और कुछ परिस्थितियों में दुर्घटना का कारण बनने का एक अच्छा तरीका है। Http://stackoverflow.com/questions/192721/why-shouldnt-i-use-obective-c-2-0-accessors-in-init-dealloc –

+0

यह लिंक एक अच्छा बिंदु लाता है, लेकिन यह अभी भी एक है बुरा विचार अगर आप केवल इसे रीडराइट गुणों के लिए उपयोग करते हैं जो पूरी तरह संश्लेषित हैं? (जिसका अर्थ है कि आप किसी संपत्ति के लिए संश्लेषण की घोषणा नहीं करते हैं और अभी भी गेटर या सेटर को ओवरराइड करते हैं) – Kevlar

+0

यह संभवत: ठीक है, पूरी तरह से संश्लेषित गुणों के साथ। लेकिन ऐप्पल इसकी गारंटी नहीं देता है कि इसकी अनुमति है और इसके खिलाफ सिफारिश की जाती है, इसलिए यह भविष्य में एसडीके में तोड़ सकता है। –

14

सिद्धांत UIView से अधिक सामान्य है। वास्तव में यह उद्देश्य-सी/कोको -release विधि से अधिक सामान्य है। यह सी malloc()/free() स्मृति कार्यों के साथ भी वैध है।

जब आपको किसी ऑब्जेक्ट या किसी मेमोरी ज़ोन की आवश्यकता नहीं है, तो पहले आप इसे रिलीज़/फ्री करें। फिर, यह सुनिश्चित करने के लिए कि आप इसे फिर से उपयोग नहीं करेंगे, आप किसी ऑब्जेक्ट या NULL को मेमोरी पॉइंटर में nil असाइन करके इस ऑब्जेक्ट या मेमोरी ज़ोन तक पहुंचने के साधनों को साफ़ करते हैं।

+4

+1 संकलक त्रुटियों मिलता है। मुख्य बिंदु यह है कि एक नल पॉइंटर को डिफ्रेंस करने से तुरंत निष्पादन बंद हो जाता है, जबकि पहले से ही मुक्त स्मृति के लिए एक पॉइंटर को संदर्भित करना कुछ समय के लिए 'काम' कर सकता है और अप्रिय बग की ओर जाता है। – zoul

+0

धन्यवाद। मैं सोच रहा हूं कि कोड कोड में हम उस पैटर्न को इतनी कम क्यों देखते हैं। मैंने इसे ऐप्पल के कोड में कभी नहीं देखा है। लेकिन ऐसा करने के लिए मुझे उचित लगता है, और मुझे लगता है कि यह किसी भी तरह से चोट नहीं पहुंचाएगा। – Thanks

+0

नमूना कोड शायद ही कभी सर्वोत्तम प्रथाओं का पालन करता है। अधिकांश नमूना कोड का लक्ष्य एक सिद्धांत, एपीआई या विधि को यथासंभव संक्षेप में प्रदर्शित करना है। – m4rkk

11

Some other method could have -retain'ed the view for some reason

जब तक आप अपने आप को dealloc लागू कर रहे हैं, यह केवल कहा जाता है जब गिनती बनाए रखने शून्य हो जाता है।

ध्यान दें कि उद्देश्य-सी में nil "ऑब्जेक्ट" को संदेश भेजना (अक्सर) बिल्कुल ठीक है। ऐसा करने से आपके प्रोग्राम को रोक देगा, लेकिन संदेश को केवल अनदेखा किया जाएगा। हालांकि, आप एक मुक्त वस्तु को एक संदेश नहीं भेज सकते हैं, जो एक दुर्घटना उत्पन्न करेगा।

तो, निम्नलिखित आपको एक त्रुटि देना होगा:

[anView release]; 
[anView doSomething]; 

लेकिन, इस तथ्य को ठीक है:

[anView release]; 
anView = nil; 
[anView doSomething]; 

यह स्वाद की बात है, लेकिन इसके बाद के संस्करण के लिए, आप में हो सकता है तथ्य यह सोचने के बजाय कि आपके काम को क्रैश करना क्यों पसंद है, कुछ क्यों नहीं किया जाता है ...

ऐप्पल के Introduction to The Objective-C 2.0 Programming Language से Sending Messages to nil भी देखें।

- (void) showHelp: (id) sender 
{ 
    if (helpController == nil) 
    { 
     helpController = [[HelpController alloc] initWithNibName: @"Help" bundle: [NSBundle mainBundle]]; 
    } 
    [self presentModalViewController: helpController animated: YES];  
} 
- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview 
    // Release anything that's not essential, such as cached data 
    [helpController release]; 
    helpController = nil; 
} 

सुंदर बहुत हर जगह है कि मैं एक ViewController कि मोडल, या अन्यथा "अस्थायी" है आवंटित:

2

मैं इस पद्धति एक बहुत का उपयोग करें। इस तरह, अगर मुझे फिर से इसकी आवश्यकता होती है तो यह चारों ओर लटकती है, लेकिन अगर स्मृति कम हो जाती है तो दूर हो जाती है।

4

ऑब्जेक्ट मुक्त होने पर -dealloc विधि को कॉल किया जाता है और ऑब्जेक्ट पर कोई अन्य विधि निष्पादित नहीं की जाएगी। इसलिए, किसी भी आवृत्ति चर को शून्य पर सेट करने से उस ऑब्जेक्ट के बाहर कोई प्रभाव नहीं पड़ता है।

यदि आप कक्षा में कहीं और ऑब्जेक्ट (एक सेटर का उपयोग किए बिना) जारी कर रहे थे, तो उस पते पर संदेश भेजने से कहीं और कोड को रोकने के लिए इंस्टेंस वैरिएबल को शून्य पर सेट करना महत्वपूर्ण होगा।

+1

"ऑब्जेक्ट पर कोई अन्य विधि निष्पादित नहीं की जाएगी" - +1 स्पष्ट के स्पष्ट स्पष्टीकरण के लिए। धन्यवाद! (जैसा कि "उस पते पर संदेश भेजने से कहीं और कोड को रोकने के लिए इंस्टेंस वैरिएबल को शून्य पर सेट करना महत्वपूर्ण है", मुझे आश्चर्य है कि एक त्रुटि संदेश प्राप्त करने पर एक अनपेक्षित संदेश को अनदेखा करना क्यों पसंद है ...) – Arjan

+3

क्योंकि सभी प्रोग्रामों में शामिल हैं बग - ग्राहक को जारी किए गए भी अच्छी तरह से परीक्षण किए गए। शून्य (मूल रूप से नो-ऑप) को संदेश भेजकर उत्पन्न त्रुटियों की तरह आमतौर पर एक मुक्त वस्तु को संदेश भेजकर उत्पन्न त्रुटियों से कम गंभीर होती है। पूर्व में आम तौर पर तर्क त्रुटियों का परिणाम होता है जहां कार्यक्रम बिल्कुल इरादे से काम नहीं करता है, बाद वाला परिणामस्वरूप दुर्घटना हो जाएगी। विकास के दौरान दुर्घटनाओं का स्वागत है क्योंकि वे बग को पाने की अनुमति देते हैं - जारी उत्पादों के लिए नहीं। – m4rkk

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

  • कोई संबंधित समस्या नहीं^_^