2008-09-15 22 views
37

यदि मेरे पास एक xib फ़ाइल से जुड़ा हुआ UILabel जैसा कुछ है, तो क्या मुझे इसे अपने दृश्य के विलुप्त होने पर रिलीज़ करने की आवश्यकता है? कारण मैं पूछता हूं क्योंकि मैं इसे आवंटित नहीं करता, जो मुझे लगता है कि मुझे इसे रिलीज़ करने की आवश्यकता नहीं है? जैसे (शीर्षक में):क्या मुझे xib संसाधनों को रिलीज़ करने की आवश्यकता है?

IBOutlet UILabel *lblExample; 

कार्यान्वयन में:

.... 
[lblExample setText:@"whatever"]; 
.... 

-(void)dealloc{ 
    [lblExample release];//????????? 
} 

उत्तर

35

तुम क्या अब सबसे अच्छा अभ्यास माना जाता है का पालन करें, तो आप चाहिए रिहाई आउटलेट गुण है, क्योंकि आप उन्हें सेट एक्सेसर में बनाए रखा जाना चाहिए था:

@interface MyController : MySuperclass { 
    Control *uiElement; 
} 
@property (nonatomic, retain) IBOutlet Control *uiElement; 
@end 


@implementation MyController 

@synthesize uiElement; 

- (void)dealloc { 
    [uiElement release]; 
    [super dealloc]; 
} 
@end 

इस दृष्टिकोण का लाभ है यह है कि स्मृति प्रबंधन अर्थशास्त्र स्पष्ट और स्पष्ट बनाता है, और यह सभी nib फ़ाइलों के लिए सभी प्लेटफॉर्म पर लगातार काम करता है।

नोट: निम्न टिप्पणियां केवल 3.0 से पहले आईओएस पर लागू होती हैं। 3.0 और बाद के संस्करण के साथ, आपको देखने के बजाय संपत्ति मूल्यों को आसानी से हटा देना चाहिए।

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

- (void)setView:(UIView *)newView { 
    if (newView == nil) { 
     self.uiElement = nil; 
    } 
    [super setView:aView]; 
} 

दुर्भाग्य से यह एक और मुद्दा को जन्म देता है।चूंकि UIViewController वर्तमान में विधि setView: एक्सेसर विधि (0xका उपयोग करके dealloc में और स्मृति चेतावनी के जवाब में कहा जाएगा ... dealloc में एक क्रैश का कारण बन जाएगा।

उपाय सुनिश्चित करने के लिए आउटलेट चर भी dealloc में nil की तैयारी में हैं है: सही ढंग से:

- (void)dealloc { 
    // release outlets and set variables to nil 
    [anOutlet release], anOutlet = nil; 
    [super dealloc]; 
} 
+0

यदि हमारे पास एक संपत्ति है, तो हम इसे self.uiElement = nil कहकर सरल बना सकते हैं; उन सभी स्थानों पर जिन्हें हम रिलीज़ करना चाहते हैं, क्योंकि यह एक बरकरार संपत्ति है, इसे वास्तव में इसे ठीक से जारी करना चाहिए और इसे बिना किसी समस्या के सेट करने के लिए सेट करना चाहिए, गुणों को बनाए रखने के फायदों में से एक। –

+1

आप आमतौर पर 'view.uiElement = nil;' 'viewDidUnload' में 'setView:' में नहीं करेंगे। और यह dealloc में 'self.anOutlet = nil;' को कॉल करने के लिए स्पष्ट होगा। –

+2

आपको self.anOutlet = nil को कॉल नहीं करना चाहिए; dealloc में। Dealloc में accessors कॉल करने के लिए यह बुरा अभ्यास है। – tobyc

0
+1

@ सोरेन: मैंने पहले से ही उस लेख को पढ़ लिया है, और इसकी सामग्री को समझ लिया है। मेरा प्रश्न आईबी xib पर तत्काल वस्तुओं के संबंध में था, जिसमें यह शामिल नहीं है। उदाहरण: मैं वास्तव में लेबल को कभी भी बना या आवंटित नहीं करता हूं, आईबी जादू वह सब करता है। तो मुझे जो जानने की ज़रूरत है वह सरल है: क्या मुझे इसे रिलीज़ करने की ज़रूरत है? – rustyshelf

0

आप, लेबल alloc करना एक अर्थ में, आईबी में यह बनाने के द्वारा।

आईबी क्या करता है, आपके आईबीओलेट्स को देखता है और उन्हें कैसे परिभाषित किया जाता है। यदि आपके पास क्लास वेरिएबल है कि आईबी किसी ऑब्जेक्ट के संदर्भ को असाइन करना है, तो आईबी आपके लिए उस ऑब्जेक्ट को एक बरकरार संदेश भेज देगा।

यदि आप गुणों का उपयोग कर रहे हैं, तो आईबी आपके द्वारा मूल्य निर्धारित करने के लिए संपत्ति का उपयोग करेगा और स्पष्ट रूप से मूल्य को बनाए रखेगा। इस प्रकार आप सामान्य रूप से बनाए रखने के रूप में IBOutlet गुण को चिह्नित करना होगा:

@property (nonatomic, retain) UILabel *lblExample; 

इस प्रकार आकाश मामले में (उपयोग करने वाली प्रॉपर्टी या नहीं) आप अपने dealloc में रिलीज फोन करना चाहिए।

+3

यह सही नहीं है। यदि आप गुणों का उपयोग नहीं करते हैं (या अपने स्वयं के एक्सेसर विधियों को लागू करते हैं), तो आपको रिलीज़ करना चाहिए या नहीं, इस पर निर्भर करता है कि आप किस प्लेटफ़ॉर्म पर हैं और आपका सुपरक्लास क्या है। यदि आप NSWindowController से प्राप्त करते हैं, उदाहरण के लिए, आप रिलीज़ नहीं करते हैं। – mmalc

4

मुझे पता चला कि मैं ऐप्पल दस्तावेज़ों में क्या ढूंढ रहा था। संक्षेप में आप गुण है कि आप जारी करने और बनाए रखने के (या बस @property, @synthesize) के रूप में अपने वस्तुओं सेट कर सकते हैं, लेकिन आप UILabels जैसी चीजों के लिए की जरूरत नहीं है:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

0

किसी भी IBOutlet है कि आपके निब के मुख्य दृश्य के एक सबव्यू को रिलीज़ करने की आवश्यकता नहीं है, क्योंकि उन्हें ऑब्जेक्ट सृजन पर ऑटोरेलीज़ संदेश भेजा जाएगा। आपके डेलोक में रिलीज करने की आवश्यकता केवल एकमात्र आईबीऑलेट आपको नियंत्रक या अन्य एनएसओब्जेक्ट जैसे शीर्ष स्तर की वस्तुएं हैं। उपरोक्त से जुड़े ऐप्पल दस्तावेज़ में यह सब उल्लेख किया गया है।

+3

यह वास्तव में गलत है। चाहे आपको शीर्ष-स्तरीय ऑब्जेक्ट्स भेजना चाहिए या नहीं, एक रिलीज संदेश इस बात पर निर्भर करता है कि आप किस प्लेटफ़ॉर्म का उपयोग कर रहे हैं और आपकी फ़ाइल के स्वामी को किस वर्ग से प्राप्त होता है। उदाहरण के लिए, यदि यह NSWindowController से प्राप्त होता है, तो आपको उन्हें रिलीज़ करने की आवश्यकता नहीं है। – mmalc

3

[anOutlet release], anOutlet = nil; 

भाग पूरी तरह से ज़रूरत से ज़्यादा अगर आप setview लिखा है है।

+0

इसका क्या मतलब है? – Casebash

+1

असल में, यह 3.0 और उसके बाद में बदल गया है, मैं समझता हूं। अब हमारे पास -viewDidUnload है और यही वह जगह है जहां हम एक्सेसर्स जारी करते हैं। –

0

आप एक संपत्ति के रूप में IBOutlet सेट न लेकिन बस एक उदाहरण चर के रूप में, आप अभी भी इसे जारी करना चाहिए। ऐसा इसलिए है क्योंकि initWithNib पर, सभी आईबीओटलेट्स के लिए स्मृति आवंटित की जाएगी। तो यह उन विशेष मामलों में से एक है जिन्हें आपको रिलीज़ करना होगा, भले ही आपने कोड में किसी भी स्मृति को बनाए रखा या आवंटित नहीं किया हो।

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

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