2009-02-24 17 views
12

मैं क्रैशिंग और मेमोरी लीक को ट्रैक करने के लिए अपनी विकास प्रक्रिया के हिस्से में हूं। एक रणनीति के रूप में, क्या आप किसी भी NSLog संदेश या कुछ ऐसे didReceiveMemoryWarning: में अधिसूचनाएं डालते हैं? इस विधि के लिए प्रलेखन बल्कि विचित्र है। क्या यह कहना सही है कि एक दुर्घटना होने से पहले, UIViewController उस विधि को ट्रिगर करेगा? क्या यह उपकरण के साथ आगे बढ़ने से पहले एक शुरुआती बिंदु है?आईओएस: didReceiveMemory चेतावनी की मदद:

उत्तर

28

ठीक है, कई बातें ध्यान रखें:

  • didReceiveMemoryWarning एक आउट-ऑफ-स्मृति दुर्घटना से पहले बुलाया जाएगा। अन्य दुर्घटनाओं नहीं। यदि आप चेतावनी को सही तरीके से संभालते हैं और स्मृति को मुक्त करते हैं, तो आप स्मृति की स्थिति से बच सकते हैं और क्रैश नहीं कर सकते हैं।
  • आप हार्डवेयर मेनू के तहत सिम्युलेटर में मैन्युअल रूप से स्मृति चेतावनी ट्रिगर कर सकते हैं। DidReceiveMemoryWarning के अपने हैंडलिंग का परीक्षण करने के लिए यह करने की अत्यधिक सिफारिश करें।
  • उपकरण आपको लीक डीबग करने में मदद करता है (हालांकि उनमें से सभी नहीं) - यह वास्तव में क्रैश के लिए उपयोगी नहीं है।
  • नहीं, मैं व्यक्तिगत रूप से NSLog का उपयोग नहीं करता - मैं डीबगिंग करते समय स्मृति चेतावनियों को तोड़ देता हूं।
+0

हाय एयरसोर्स, क्या मैं पूछ सकता हूं कि 'सिम्युलेटर -> हार्डवेयर -> मेमोरी चेतावनी अनुकरण' के लिए क्या उपयोग किया जाता है? जब भी मैं इसे क्लिक करता हूं, मुझे केवल एक संदेश मिलता है "अनुरूपित स्मृति चेतावनी प्राप्त होती है।" कंसोल में। मैं इसे 'समस्याओं को दूर करने' के लिए कैसे उपयोग करूं? धन्यवाद। – lionfly

+0

@lionfly - आपको स्मृति चेतावनी के जवाब में, जितना संभव हो उतना स्मृति मुक्त करना चाहिए। स्मृति चेतावनी को सिम्युलेट करने से आप उस कोड पथ को चेक (और डीबग) कर सकते हैं। –

3

didReceiveMemoryWarning का उद्देश्य आपको दुर्घटना से बचने के लिए स्मृति या पॉप दृश्यों को मुक्त करने का मौका देना है। आप इसे किसी भी अनुमानित बिंदु पर प्राप्त नहीं करेंगे क्योंकि यह इस बात पर निर्भर करता है कि उपयोगकर्ता क्या कर रहा है। उदाहरण के लिए, यदि उपयोगकर्ता आइपॉड को सुन रहा है, तो वहां कम उपलब्ध स्मृति है और आप इसे जल्द ही प्राप्त करेंगे।

अंगूठे का सामान्य नियम यह है कि आपके पास काम करने के लिए लगभग 8 एमबी रैम है। जब आप इसके करीब आते हैं तो आप घटना को उठाए जाने की उम्मीद कर सकते हैं। यदि आप जानबूझ कर उस रैम को उठा रहे हैं तो आपके पास इसके बारे में कुछ करने की योजना होनी चाहिए।

4

अद्यतन iOS 6 के रूप में, UIViewController विचारों नहीं रह गया है स्मृति चेतावनी के जवाब में उतार दिया है। इसके बजाय didReceiveMemoryWarning कहलाते समय किसी भी संसाधन को रिलीज़ करने के लिए बस अपना सर्वश्रेष्ठ प्रयास करें (उदा। कैश डेटा)।

अद्यतन
मैं अपने मूल जवाब लिखा जब मैं एक एंग्री यंग मैन था, समय बदल गया है और मूल रूप से, यह गलत है।

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

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

जब स्मृति प्रचुर मात्रा में होती है, तो कुछ भी अनलोड नहीं होता है और सब कुछ रेशमी चिकनी होता है, और जब स्मृति कम होती है, तो धीरे-धीरे काम करते रहें। अब मैं कहूंगा कि सीमित स्मृति समस्या का यह समाधान आदर्श है।

इस स्मृति पार्लर चाल का लाभ लेने के लिए, ओवरलोड UIViewController तरीकों viewDidLoad, viewDidUnload, और viewWillUnload (iOS5, उपयोगी अगर उतारने राज्य आपके विचार की आवश्यकता है अभी भी मौजूद हैं करने के लिए, उदाहरण के लिए यदि आप अपने ओपन लीक करने के लिए नहीं करना चाहते हैं बनावट & आईओएस 4 पर रेंडर बफर, आप इसे didReceiveMemoryWarning ओवरलोड करके और अपने दृश्य की दृश्यता को ट्रैक करके अनुकरण कर सकते हैं)।

मूल, अधिक bilious उत्तर

didReceiveMemoryWarning बिल्कुल बेकार है।

कोई गारंटी नहीं है कि यदि आप स्मृति को मुक्त करते हैं (यहां तक ​​कि यह सब भी) कि आप मारे नहीं जाएंगे।

मेरी कड़वा अनुभव में यह आम तौर पर 2.x/3.0 पर इस तरह काम करता है:

  1. mediaserverd स्मृति का एक समूह

  2. मेरे ऐप को मार डाला जाता है

दुर्भाग्य से लीक , रेपर कभी mediaserverd की हत्या के बारे में सोचता है।

तो अगर स्मृति उपयोग आपकी गलती नहीं है, तो आप वास्तव में केवल दो विकल्प मिल गया है:

  1. रिबूट करने के लिए कहें (उपयोगकर्ता मान लिया गया यह आपकी गलती है, एक कटु समीक्षा लिखता है)

  2. आशा अपराधी दुर्घटनाओं (mediaserverd अक्सर बाध्य!)

+0

समय पर मार्च। viewDidUnload अब इन नोट्स के साथ बहिष्कृत है, "दृश्य अब कम स्मृति स्थितियों के तहत शुद्ध नहीं हैं और इसलिए इस विधि को कभी नहीं कहा जाता है।" और "आईओएस 6 और बाद में, आपके व्यू कंट्रोलर में विचारों और अन्य वस्तुओं के संदर्भों को साफ़ करना अनावश्यक है।"- [स्रोत] (https://developer.apple.com/reference/uikit/uiviewcontroller/1621383-viewdidunload?language=objc) – jk7

+0

मैं इस जवाब को सिर्फ दूसरे दिन अपडेट करने की सोच रहा था! –

5

उपयोगकर्ता कुछ एप्लिकेशन को छोड़ दिया खोलेंगे तो आपको अपने dispos पर बहुत कम स्मृति होगा अल। तो कभी-कभी didReceiveMemoryWarning को केवल 1 एमबी उपयोग के बाद सिस्टम द्वारा बुलाया जा सकता है।

सिस्टम आपके सभी व्यू कंट्रोलर पर इस विधि को कॉल करता है, यदि आप अपने प्रत्येक व्यू कंट्रोलर में एनएसएलओजी डालते हैं, तो आप उसे नोटिस करेंगे।

फिर स्वचालित रूप से विधि viewDidUnload आपके सभी दृश्य नियंत्रकों पर सिस्टम द्वारा कॉल की जाएगी (dealloc नहीं)। तो आपको वहां अपने सभी डीलोकेशन निर्देशों को रखना होगा।

आपको बहुत सारे प्रयोग करना पड़ता है क्योंकि यदि आपका ऐप जटिल है तो आपको इसे प्रबंधित करने से पहले कई दुर्घटनाओं का सामना करना पड़ेगा।

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