2011-06-07 13 views
229

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

एक्सकोड 4.2 के साथ आने वाला टूलचेन LLVM compiler के नवीनतम संस्करण के साथ स्वचालित संदर्भ गिनती (एआरसी) प्रस्तुत करता है, जो संकलक को स्मृति के लिए आपके सामान को प्रबंधित करने के द्वारा पूरी तरह से इस समस्या से दूर हो जाता है। यह बहुत अच्छा है, और यह बहुत सारे अनावश्यक, सांसारिक विकास के समय में कटौती करता है और बहुत सी लापरवाही मेमोरी लीक को रोकता है जो उचित बनाए रखने/रिलीज संतुलन के साथ ठीक करना आसान होता है। जब भी आप अपने मैक और आईओएस ऐप्स के लिए एआरसी सक्षम करते हैं तो ऑटोरेलीज पूल को अलग-अलग प्रबंधित करने की आवश्यकता होती है (क्योंकि आपको अपना खुद का NSAutoreleasePool एस आवंटित नहीं करना चाहिए)।

लेकिन क्या अन्य मेमोरी लीक यह नहीं को रोकने मैं अब भी के लिए बाहर देखने के लिए कि क्या है?

बोनस के रूप में, मैक ओएस एक्स और आईओएस पर एआरसी और मैक ओएस एक्स पर कचरा संग्रह के बीच अंतर क्या हैं?

उत्तर

257

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

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

आप प्रतिनिधियों जैसे चीजों के लिए इन क्वालीफायरों का उपयोग करेंगे, जहां आप नहीं चाहते हैं कि ऑब्जेक्ट अपने प्रतिनिधि को बनाए रखे और संभावित रूप से एक चक्र का नेतृत्व कर सके।

महत्वपूर्ण स्मृति-संबंधित चिंताओं का एक और जोड़ा कोर फाउंडेशन ऑब्जेक्ट्स और malloc() का उपयोग करके आवंटित स्मृति char* जैसे प्रकारों के लिए आवंटित किया गया है। एआरसी इन प्रकारों का प्रबंधन नहीं करता है, केवल उद्देश्य-सी ऑब्जेक्ट्स, इसलिए आपको अभी भी स्वयं से निपटने की आवश्यकता होगी। कोर फाउंडेशन प्रकार विशेष रूप से मुश्किल हो सकते हैं, क्योंकि कभी-कभी उन्हें ऑब्जेक्टिव-सी ऑब्जेक्ट्स के मिलान के लिए ब्रिज किया जाना चाहिए, और इसके विपरीत। इसका मतलब यह है कि सीएफ प्रकारों और उद्देश्य-सी के बीच ब्रिजिंग करते समय नियंत्रण को एआरसी से आगे और आगे स्थानांतरित करने की आवश्यकता होती है। इस ब्रिजिंग से संबंधित कुछ कीवर्ड जोड़े गए हैं, और his lengthy ARC writeup में माइक एश के विभिन्न ब्रिजिंग मामलों का एक बड़ा विवरण है।

इसके अतिरिक्त, कई अन्य कम बार-बार होते हैं, लेकिन अभी भी संभावित समस्याग्रस्त मामले हैं, जो published specification विस्तार से आगे बढ़ते हैं।

अधिकांश नए व्यवहार, जब तक उनके पास एक मजबूत सूचक होता है, तब तक वस्तुओं को रखने के आधार पर, मैक पर कचरा संग्रह के समान ही होता है। हालांकि, तकनीकी आधार बहुत अलग हैं। ऑब्जेक्ट्स को साफ करने के लिए नियमित अंतराल पर चलने वाली कचरा कलेक्टर प्रक्रिया होने की बजाय, अब स्मृति की इस शैली को कठोर बनाए रखने/रिलीज नियमों पर निर्भर करता है, जिसे हमें उद्देश्य-सी में पालन करने की आवश्यकता होती है।

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

कचरा संग्रह बनाम एआरसी पर अधिक के लिए, this very interesting response by Chris Lattner on the Objective-C mailing list देखें, जहां वह उद्देश्य-सी 2.0 कचरा संग्रह पर एआरसी के कई फायदे सूचीबद्ध करता है। मैंने जीसी मुद्दों में से कई में भाग लिया है।

+2

विस्तार जवाब के लिए धन्यवाद। मेरे पास एक ही समस्या थी जहां मैंने _unsafe_unretained के तहत एक प्रतिनिधि को परिभाषित किया और मेरा आवेदन क्रैश हो गया, बाद में इसे मजबूत करके बदल दिया गया लेकिन अब इसमें स्मृति रिसाव है। तो, मैंने इसे कमजोर कर दिया और एक आकर्षण की तरह काम करता है। – chathuram

+0

@ichathura वाह! आपने मुझे एआरसी मूर से बचाया। CMPopTipView का उपयोग करते समय मुझे एक ही दुर्घटना का सामना करना पड़ा। – Nianliang

+0

@ ब्रैडलर्सन: "आपके पास कचरा इकट्ठा करने वाले प्लेटफॉर्म पर अनुभवी समस्याएं या शर्टूथ मेमोरी प्रोफाइल नहीं हैं"। मैं स्कोप-आधारित पुनर्विचार और संदर्भ गणना से बहुत खराब प्रदर्शन से खराब रोकथाम और सॉटूओथ मेमोरी प्रोफाइल की अपेक्षा करता हूं, इसलिए मैं एक वास्तविक तुलना देखना चाहता हूं। –

14

एआरसी गैर-ओबीजेसी मेमोरी के साथ आपकी मदद नहीं करेगा, उदाहरण के लिए यदि आप malloc() कुछ करते हैं, तो आपको अभी भी free() की आवश्यकता है।

एआरसी को performSelector: द्वारा बेवकूफ बनाया जा सकता है यदि संकलक यह नहीं समझ सकता कि चयनकर्ता क्या है (संकलक उस पर चेतावनी उत्पन्न करेगा)।

एआरसी ओबीजेसी नामकरण सम्मेलनों के बाद भी कोड उत्पन्न करेगा, इसलिए यदि आप एआरसी और एमआरसी कोड मिश्रण करते हैं तो आप आश्चर्यजनक परिणाम प्राप्त कर सकते हैं यदि एमआरसी कोड ऐसा नहीं करता है जो संकलक नामों के वादे को सोचता है।

0

एआरसी CoreFoundation प्रकारों का प्रबंधन भी नहीं करेगा। आप उन्हें 'पुल' कर सकते हैं (CFBridgingRelease() का उपयोग करके) लेकिन केवल अगर आप इसे उद्देश्य-सी/कोको ऑब्जेक्ट के रूप में उपयोग करने जा रहे हैं। ध्यान दें कि CFBridgingRelease केवल कोरफॉउंडेशन को 1 से गिनती बनाए रखता है और इसे ऑब्जेक्टिव-सी के एआरसी में ले जाता है।

4

मैं निम्नलिखित 4 मुद्दों की वजह से अपने आवेदन में मेमोरी लीक अनुभव:

  1. NSTimers अमान्य नहीं जब दृश्य नियंत्रक
  2. खारिज जब दृश्य नियंत्रक खारिज NSNotificationCenter के लिए किसी भी पर्यवेक्षकों को दूर करने को भूलना।
  3. ब्लॉक में स्वयं के लिए मजबूत संदर्भ रखते हुए।
  4. दृश्य नियंत्रक गुण

में प्रतिनिधियों को मजबूत संदर्भ का उपयोग करना सौभाग्य से मैं निम्न ब्लॉग पोस्ट में आए और उन्हें सही करने में सक्षम था: http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/