2011-12-16 9 views
8

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

इस कोड है:

-(void)releaseMySelf{ 
    for (int i=myRetainCount; i>1; i--) { 
     [self release]; 
    } 
    [self autorelease]; 
} 

जहाँ तक मुझे पता है, ऑब्जेक्टिव-सी स्मृति प्रबंधन मॉडल में, पहला नियम है कि उद्देश्य यह है कि किसी अन्य वस्तु आबंटित करता है, भी इसे जारी करने की जिम्मेदार है भविष्य। यही कारण है कि मैं इस कोड के अर्थ को समझ नहीं पा रहा हूं। क्या कोई मतलब है?

+4

मुझे लगता है कि "पवित्र गाय!" – albertamg

+20

कोई आश्चर्य नहीं कि उसने कंपनी छोड़ दी; इस तरह का कोड एक निश्चित संकेत है कि वह अपने सिर पर रास्ते में था, इस बारे में कोई समझ नहीं थी कि ऐप कैसे लिखना है और उचित तरीकों को सीखने का कोई मौका नहीं है। अगर मुझे लगता है कि एक परियोजना में (और मैंने - एक परामर्श सेवा कंपनी चलायी है जो परेशान परियोजनाओं पर "साफ" करती है), तो मैं तुरंत लाल झंडा फेंक दूंगा और मांग करता हूं कि उस व्यक्ति द्वारा लिखे गए कोड की प्रत्येक पंक्ति की समीक्षा की जाए । (ऐसा लगता है कि वह ऑब्जेक्ट की वास्तविक बरकरार गिनती से अलग एक बरकरार गिनती को बनाए रख रहा है ... उस खेल पर 2 लाल झंडे।) – bbum

+9

मुझे लगता है कि "मैं जानना चाहता हूं कि किसने लिखा है, इसलिए मैं कभी भी उसके साथ काम नहीं कर सकता " –

उत्तर

17

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

हालांकि यहां कई उत्तरों देखें उदा। here और here और here

Apple's memory management concepts पढ़ें।

पहले लिंक से Apple

एक बोली retainCount विधि किसी भी लंबित autorelease संदेशों रिसीवर के लिए भेजा के लिए खाते में नहीं है भी शामिल है।

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

+3

एक तरफ नोट पर, मैं आपको कोड के इस टुकड़े को हटाने और स्थिर विश्लेषक के माध्यम से अपना कोड चलाने की सलाह देता हूं। यह दिखाना चाहिए कि वस्तुओं को कहाँ जारी किया जाना चाहिए था। – Eimantas

3

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

2

कोड का अर्थ ऑब्जेक्ट को अभी डिलीकेट करने के लिए मजबूर करना है, इससे कोई फर्क नहीं पड़ता कि भविष्य के परिणाम क्या हो सकते हैं। (और परिणाम होंगे!)

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

उम्मीद है कि इस तरह लिखा कोड बस दुर्घटनाग्रस्त हो जाएगा। शायद मूल लेखक ने कहीं और स्मृति को लीक करके इन दुर्घटनाओं से परहेज किया।

+1

धन्यवाद बहुत दोस्त! मुझे यही लगता है, यह एक भयानक कोड है। – Ricardo

7

चूंकि सभी उत्तर मेरे रीटेनकाउंट को [स्वयं retainCount] के रूप में गलत तरीके से पढ़ते प्रतीत होते हैं, इसलिए मुझे यह कारण बताएं कि यह कोड क्यों लिखा जा सकता है: यह हो सकता है कि यह कोड किसी भी तरह से धागे को फैला रहा हो या अन्यथा ग्राहक इसके साथ पंजीकरण कर सकें, और myRetainCount प्रभावी रूप से उन ग्राहकों की संख्या है, जो वास्तविक ओएस को अलग-अलग गिनती से अलग रखते हैं। हालांकि, प्रत्येक ग्राहक को अपनी ओबीजेसी-शैली भी बरकरार रख सकती है।

तो इस फ़ंक्शन को ऐसे मामले में बुलाया जा सकता है जहां अनुरोध निरस्त हो गया है, और केवल सभी ग्राहकों को एक ही समय में निपटाना, और बाद में सभी रिलीज निष्पादित कर सकते हैं। यह एक अच्छा डिज़ाइन नहीं है, लेकिन अगर कोड काम करता है, (और आपने intRetainCount = [self retainCount], या बनाए रखने/रिलीज़ करने के ओवरराइड को छोड़ दिया नहीं है) कम से कम यह आवश्यक नहीं है।

हालांकि, यह वास्तव में जिम्मेदारियों का खराब वितरण या किसी भी चीज को सुधारने के बिना बनाए रखने वाले सर्किलों से बचने के लिए हैकनीड प्रयास की संभावना है।

+0

हालांकि यह अभी भी कार्यान्वित करने का सही तरीका नहीं है - यह अभी भी लेखक को स्मृति प्रबंधन सही नहीं है - बनाए रखने/रिलीज आदि धागे के साथ काम करता है – Mark

+0

धागे का मतलब केवल उन ग्राहकों के उदाहरण के रूप में किया गया था जो आम तौर पर पंजीकरण/पंजीकरण नहीं करेंगे, उदाहरण के लिए थ्रेड पूल या "सभी रद्द करें" व्यवहार के लिए। – uliwitness

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

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