2009-08-17 24 views
45

ध्यान दें: यह सवाल outdated- viewDidUnload बहिष्कृत है आईओएस 6.UIViewController viewDidUnload कब कहा जाता है?

जब UIViewController के viewDidUnload स्वचालित रूप से कहा जाता हो जाता है है? हां, मुझे पता है, जब दृश्य अनलोड हो जाता है। लेकिन यह स्वचालित रूप से कब होता है? मैं इसे मैन्युअल रूप से कैसे कर सकता हूं? धन्यवाद।

+4

ऐसा लगता है कि इसे जरूरी नहीं कहा जाता है; एक UIViewController बिना कॉलिंग व्यूडिडलोड के बिना हटाया जा सकता है। – beetstra

+0

व्यापक परीक्षण के बाद, मैं निश्चित रूप से देखता हूं कि viewDidUnload कभी-कभी नहीं कहा जा सकता है। मैं दृश्य नियंत्रकों को बिना देखने के dealloc'd मिल रहा है DidUnload बुलाया जा रहा है। –

+0

इस प्रश्न को हटाया जाना चाहिए। viewDidUnload को बहिष्कृत किया गया है और अब आईओएस 6 में नहीं कहा जाता है। –

उत्तर

42

यदि आप सिम्युलेटर (मेनू में देखें) में मेमोरी चेतावनी जारी करते हैं, तो इसे किसी दृश्य से जुड़े किसी भी व्यू कंट्रोलर के लिए बुलाया जाएगा जो दिखाई नहीं दे रहा है।

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

आम तौर पर आप किसी भी आईबीओटलेट्स को रिलीज करते हैं, जिसे इस विधि में रिलीज़ किया जाना चाहिए (और संदर्भों को शून्य पर सेट किया जाना चाहिए)।

+0

यह मेरे ऐप के लिए नहीं बुलाया जाएगा क्योंकि मेरे पास केवल एक बार एक दृश्य नियंत्रक होता है, जब मैं उन्हें पहले स्विच करता हूं तो मैं वर्तमान (de.vc = nil) को चालू करता हूं (पर्यवेक्षण से हटाने के बाद)। – mk12

+0

मैं आईबीओटलेट्स का उपयोग नहीं करता, मैं आईबी का उपयोग नहीं करता हूं। – mk12

+0

मुझे पूरा यकीन है कि आप सही हैं, अगर आपके पास एक समय में केवल एक वीसी है तो दृश्य कभी भी अनलोड नहीं किया जाएगा। सबसे आम मामला तब होता है जब आप नेविगेशन नियंत्रक का उपयोग करते हैं, और जिन दृश्यों से आप नेविगेट किया गया है वे अभी भी वहां हैं ... यदि आप आईबी का उपयोग नहीं करते हैं, भले ही आप एक ही नियम के लिए संदर्भ रखने वाले सबव्यूज जोड़ते हैं - संदर्भ को निपटाएं (हालांकि फिर से यह आपके मामले में लागू नहीं होता है)। –

17

-viewDidUnload जब भी व्यू कंट्रोलर की दृश्य संपत्ति को शून्य पर सेट किया जाता है, या तो मैन्युअल रूप से या आमतौर पर didReceiveMemoryWarning: के माध्यम से कहा जाता है।

+0

मेरे पास एक परिदृश्य है जहां मैं चाहता हूं-viewDidUUload को UIViewController पर आग लगाना जो UIPopoverController द्वारा होस्ट किया गया था। पॉपओवर को खारिज कर दिए जाने के बाद, मैं मैन्युअल रूप से व्यू कंट्रोलर के दृश्य को नकार रहा हूं, लेकिन -viewDidUnload अभी भी नहीं निकाल दिया गया है। कोई विचार क्यों नहीं? – dreyln

+0

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

+0

हां, मेरे पास ब्रेकपॉइंट और कुछ कोड था जो टाइमर को अमान्य करता है। ब्रेकपॉइंट कभी हिट नहीं हुआ था और मेरा टाइमर चल रहा था (कंसोल पर संदेश लॉग कर रहा था)। मैंने यह भी सत्यापित किया कि मेरे पॉपओवर की सामग्री दृश्य नियंत्रक सही था और शून्य नहीं था। आश्चर्य है कि दृश्य अभी भी तकनीकी रूप से दिखाई दे रहा है। मैं -पॉपओवर नियंत्रक DidDismissPopover में विधि को देख रहा हूं: विधि। – dreyln

37

इसके अलावा स्वयं एक स्मृति सिम्युलेटर में चेतावनी जारी करने के लिए, आप

- (void)_simulateLowMemoryWarning { 
    // Send out MemoryWarningNotification 
    [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification 
                 object:[UIApplication sharedApplication]]; 
    // Manually call applicationDidReceiveMemoryWarning 
    [[[UIApplication sharedApplication] delegate] applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]]; 
} 

साथ प्रोग्राम के एक जारी कर सकते हैं इसके बाद आप इस एक टाइमर

static NSTimer *gLowMemoryTimer = nil; 

- (void)stopLowMemoryTimer { 
    [gLowMemoryTimer invalidate]; 
    gLowMemoryTimer = nil; 
} 

- (void)startLowMemoryTimer { 
    if (gLowMemoryTimer) { 
    [self _stopLowMemoryTimer]; 
    } 
    gLowMemoryTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_simulateLowMemoryWarning) userInfo:nil repeats:YES]; 
} 
+6

ऐप का परीक्षण करने के लिए शानदार विचार। – Guillaume

+0

यह एक अच्छा विचार है, यद्यपि इसका उपयोग केवल परीक्षण के लिए किया जाएगा, इसलिए संभवतया यूआईपीप्लिकेशन में निजी विधि का उपयोग करना सबसे अच्छा होगा, जब वास्तविक स्मृति चेतावनी होती है, बस अगर यह कुछ और करता है: '[[ यूआईप्लिकेशंस साझा अनुप्रयोग] प्रदर्शन चयनकर्ता: @ चयनकर्ता (_performMemory चेतावनी)]; ' –

3

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

9

आईओएस 6.x और बाद में

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन मैं एक जवाब अर्थात् iOS 6 में viewDidUnload एपीआई में परिवर्तन है कि IOS 6 में viewDidUnload नहीं है के बारे में प्रस्तुत की जानी चाहिए लग रहा है अब (बिल्कुल) कहा जाता है और इसे हटा दिया गया है।

+2

इसके आगे: यदि आप आईओएस 5 के खिलाफ तैनाती करते हैं तो आपको अभी भी 'viewDidUnload' कार्यान्वयन' लिखना चाहिए, लेकिन यह महत्वपूर्ण नहीं है कि आईओएस पर चलाने के लिए कोई तर्क न हो 6 वहां। – mxcl

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