2010-03-01 12 views
14

मुझे कुछ समय के लिए धारणा के तहत किया गया है कि viewDidUnload हमेशा नियंत्रक को हटाए जाने पर बुलाया जाता है। क्या यह एक सही धारणा है?दृश्य में रिलीज करेंडिडलोड और दोनों को डेलोक करें?

मैं कुछ अजीब चीज़ों की खोज कर रहा हूं, और अपने नियंत्रक के viewDidUnload में ब्रेकपॉइंट सेट किया है और यह dealloc है। ऐसा लगता है कि dealloc कहा जाता है, लेकिन viewDidUnload विधि कभी नहीं कहा जाता है। मैंने अपने dealloc पर self.view = nil भी जोड़ा और यह अभी भी इसे कॉल नहीं कर रहा था।

क्या इसका मतलब यह है कि viewDidUnload विधि में जारी किए गए दृश्य ऑब्जेक्ट्स को मेरे dealloc विधि में रिलीज़ होने की आवश्यकता है ताकि वे वास्तव में दूर जा सकें?

मुझे पता है कि स्टैक ओवरव्लो पर viewDidUnload पर कई अन्य प्रश्न हैं, लेकिन कोई भी विशेष रूप से 2 विधियों के बीच रिलीज स्टेटमेंट के डुप्लिकेशन के बारे में इस समस्या को संबोधित नहीं करता है।


3.1.2 एसडीके पर एक ताजा परियोजना में एक और अधिक ठोस उदाहरण के:

@implementation TestViewController 

@synthesize label; 

- (IBAction)push { 
    TestViewController *controller = [[[TestViewController alloc] initWithNibName:@"TestViewController" bundle:nil] autorelease]; 
    [self.navigationController pushViewController:controller animated:YES]; 
} 

- (void)viewDidUnload { 
    self.label = nil; 
    NSLog(@"viewDidUnload was called"); 
} 

- (void)dealloc { 
    [super dealloc]; 
    NSLog(@"label retain count: %i", [label retainCount]); 
} 

@end 

मेरा ऐप प्रतिनिधि के रूप में यह जड़ नियंत्रक है इनमें से किसी एक के साथ एक सरल नेविगेशन नियंत्रक पैदा करता है। जब मैं push से 3 बार लिंक बटन को टैप करता हूं, और फिर बैक बटन को तीन बार दबाता हूं, तो निम्न आउटपुट उत्पन्न होता है।

ViewDidUnloadTest[2887:207] label retain count: 2 
ViewDidUnloadTest[2887:207] label retain count: 2 
ViewDidUnloadTest[2887:207] label retain count: 2 

जो 2 उच्च है जो मुझे लगता है कि यह होगा। एक बार दृश्य द्वारा और एक बार नियंत्रक द्वारा बनाए रखा। लेकिन dealloc के बाद मुझे उम्मीद थी कि दृश्य मेरे लेबल को जारी कर दिया जाएगा, और नियंत्रक को viewDidUnload पर कॉल करने और इसे जारी करने के लिए जाना होगा। यद्यपि इस बिंदु पर गिनती फेंकने में autorelease हो सकता है।

लेकिन कम से कम यह है कि viewDidUnload बिल्कुल बुलाया हो रही है, जो इस सवाल का जवाब यहाँ के विपरीत स्पष्ट है: Are viewDidUnload and dealloc always called when tearing down a UIViewController?

शायद मैं बस नियंत्रकों पर मेरे सारे dealloc तरीकों में [self viewDidUnload] बुलाना चाहिए? ऐसा होने से भी बदतर यह है कि मैंने संपत्ति को दो बार शून्य करने के लिए सेट किया है, है ना?

उत्तर

20

जब तक आपको एक सतत चक्र तोड़ने की आवश्यकता न हो, आपको आमतौर पर केवल dealloc विधि में ऑब्जेक्ट्स जारी करना चाहिए। viewDidUnload एक अपवाद है; इसे कम स्मृति स्थितियों में बुलाया जाता है और आप जो कुछ भी कर सकते हैं उसे छोड़ने के लिए इस्तेमाल किया जाना चाहिए।

यदि आपको उन्हें कहीं और रिलीज़ करने की आवश्यकता है, तो release के बाद हमेशा संदर्भ को शून्य पर सेट करें। यह आपके ऐप को बाद में उड़ने से बचाएगा (संभवतः dealloc में)।

ध्यान दें कि दस्तावेज़ीकरण स्पष्ट रूप से कहता है कि दृश्य संपत्ति पहले से ही शून्य होगी जब viewDidUnload कहा जाता है।

+0

तो आप कह रहे हैं "हां, आपको अपने' dealloc' में बनाए गए गुणों को रिलीज़ करने की आवश्यकता है भले ही आप उन्हें 'viewDidUnload' विधि' में रिलीज़ और निरस्त कर दें? –

+3

बिल्कुल; viewDidUnload कम स्मृति स्थितियों के लिए है और dealloc सफाई के लिए है। दोनों ऑर्थोगोनल हैं। – bbum

+1

यह उदाहरणों से आने वाला एक बहुत ही भ्रमित बिंदु है! अधिकांश उदाहरण दृश्यों को देखने के लिए सेट किए जा रहे हैं DidUnload।यह समझाने में विफल रहता है कि कुछ शून्य के लिए सेट होने के बाद, आप इसे जारी नहीं कर सकते हैं और इसे अस्वीकार करने की उम्मीद कर सकते हैं! इस पर ध्यान दिए बिना, आप जगह पर मेमोरी लीक के साथ खत्म हो जाएगा। आपकी मददगार पोस्ट के लिए धन्यवाद। – jocull

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