IOS6 में ViewController जीवन चक्र

आप में से कुछ ने देखा होगा कि viewControllers अब iOS6 में viewWillUnload और viewDidUnload का अनुरोध नहीं करते हैं। ऐसा इसलिए है क्योंकि नियंत्रक अब अपने विचारों को स्वचालित रूप से अनलोड नहीं करते हैं।
आपका पहला विचार "ठीक है, मैं कम स्मृति चेतावनी के साथ अपने विचार को मैन्युअल रूप से कैसे उतार सकता हूं?" यह एक कदम पीछे की तरह दिखता है। ”
फिर आप जवाब तलाशते हैं और कुछ लिखते हैं:

- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; if([self isViewLoaded] && ![[self view] window]) { [self setView:nil]; } } 


हालांकि, इस पद्धति का उपयोग करने की आवश्यकता नहीं है, यह यूआईवाइवाई के मूल समर्थन में कुछ परिवर्तनों के कारण संभावित रूप से हानिकारक है। इसलिए, व्यवहार में, आपको स्मृति की कमी की रिपोर्ट करते समय शायद ही कभी नियंत्रक से दृश्य को मैन्युअल रूप से अनलोड करने की आवश्यकता होती है। (और सिद्धांत रूप में, कभी नहीं)

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

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

लेकिन परत का मुख्य भाग (मेमोरी उपयोग के संदर्भ में) एक बिटमैप है। परत ही 48 बाइट्स है, और स्क्रीन आकार की परवाह किए बिना मानक UIView केवल 96 बाइट्स है। परत के लिए मेमोरी की खपत स्क्रीन पर छवि बिटमैप के आकार पर निर्भर करती है। उदाहरण के लिए, iPad रेटिना के लिए, एक पूर्ण-स्क्रीन छवि 12mb तक पहुंच सकती है।

IOS6 में उपयोग किया जाने वाला दृष्टिकोण यह है कि जब पर्याप्त मेमोरी नहीं होती है, तो लेयर के बिटमैप को मेमोरी से अनलोड किया जाता है, और UIView और CALayer ऑब्जेक्ट्स को बरकरार रखा जाता है। यह काफी उचित है, क्योंकि ऑब्जेक्ट्स, जैसा कि ऊपर उल्लेख किया गया है, स्मृति की एक छोटी मात्रा पर कब्जा कर लेते हैं, और बिटमैप को फिर से ड्राइंटर का उपयोग करके बनाया जा सकता है।

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

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

अब इस बारे में विचार और उनकी परतें क्यों मायने रखती हैं। प्रत्येक परत में एक सामग्री गुण होता है जो बिटमैप को संग्रहीत करने वाली किसी वस्तु को इंगित करता है।

यह एक निजी वस्तु है, कैबकिंगस्टोर वर्ग का एक उदाहरण जिसमें वर्तमान बिटमैप है, साथ ही कुछ मेटाडेटा (जैसे कि छवि में एक अल्फा चैनल है और प्रति पिक्सेल कितने बाइट्स का उपयोग किया जाता है)। इस प्रकार, यह कैबकिंगस्टोर है जिसे स्मृति समाप्त होने पर नष्ट कर दिया जाना चाहिए।

हालाँकि, सूक्ष्मता यह है कि स्मृति की कमी के साथ, कैबिंगस्टोर (भंडारण) नष्ट नहीं होता है। यदि कम मेमोरी के बारे में चेतावनी के समय दृश्य सक्रिय नहीं है, तो इसकी परत के भंडारण को अस्थिरता के साथ चिह्नित किया जाता है। यह ध्वज, इस संदर्भ में, डीलक्लोकेशन के समान है और विभिन्न उद्देश्यों के लिए इसके उपयोग की अनुमति देता है। ध्वज और डील-डौल के बीच का अंतर यह है कि "टैग की गई" मेमोरी को वास्तव में पुनर्स्थापित किया जा सकता है, यह अनियमित रूप से नहीं खोया गया है।

विचार करें कि यह एक महान अनुकूलन क्यों है। यदि दृश्य (CABackingStore) दृश्य (या बल्कि परत) पर नष्ट हो गया था, तो अगली बार दृश्य को drawRRect करके इसे फिर से बनाना चाहिए:। यह एक संसाधन-गहन ऑपरेशन है और इसे टाला जाना चाहिए। अपनी भंडारण परत को बहाल करने की क्षमता रखने से एक नई कॉल ड्राइनरक्ट से बच सकते हैं:।

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

Source: https://habr.com/ru/post/In153767/


All Articles