2009-01-22 17 views
6

यहां मेरा मामला है: मेरे पास संपर्क दिखाने वाला एक टेबल व्यू है। नेविगेशन बार में बटन जोड़ें डेटा प्रविष्टि के लिए एक और दृश्य लोड करने के लिए प्रयोग किया जाता है। इस नए दृश्य में टेबल हेडर में छवियां हैं, और प्रत्येक तालिका कक्ष में UITextField या UITextView है। जब मैं रद्द करता हूं, तो दृश्य पॉप आउट हो जाता है और स्मृति जारी होती है।आईफोन डेवलपमेंट - EXC_BAD_ACCESS त्रुटि कोई स्टैक ट्रेस

यहाँ मेरी मुद्दा है: जब मैं "जोड़ें" इंटरफ़ेस खोलने, UITextField या UITextView में से किसी में एक मूल्य प्रदान करते हैं और प्रेस "रद्द करें" वापस जनक दृश्य में जाने के लिए करने के लिए, मैं एक EXC_BAD_ACCESS त्रुटि मिलती है। जब मैं इसका पता लगाता हूं, तो "कंट्रोलर जोड़ें" कॉल को ठीक से कॉल करता है, लेकिन [सुपर डेलोक] के बाद जब मैं जारी रखता हूं, तो यह त्रुटि फेंकता है। बस यह, कोई निशान नहीं है, हालांकि मैं NSZombieEnabled का उपयोग कर रहा हूं। जब मैं उपकरण के साथ कोड चलाने के लिए, मैं किसी भी त्रुटि :(

मुझे आशा है कि मैं इस मुद्दे को समझाने में स्पष्ट कर रहा हूँ नहीं मिलता है। किसी भी संकेत दिए गए? धन्यवाद।

+0

समस्या जादुई जब मैं से [tableView रिहाई] को दूर गायब हो जाता है मेरी "संपर्क जोड़ें" नियंत्रक वर्ग की dealloc विधि। लेकिन मुझे tableView ऑब्जेक्ट को छोड़ना चाहिए, है ना? हालांकि मैं nib फ़ाइल का उपयोग कर रहा हूं - और तालिका बनाई गई है 'आईबीओलेटलेट' देखें। – Mustafa

+1

नहीं, आपको नहीं करना चाहिए। याद रखने का नियम यह है कि 'यदि आपने स्पष्ट रूप से आवंटित नहीं किया है, तो इसे कॉपी या बनाए रखें, तो आप इसे स्पष्ट रूप से रिलीज़ नहीं करते हैं।' –

उत्तर

8

इस त्रुटि का सबसे आम कारण है जब आप किसी ऑब्जेक्ट को रिलीज़ करते हैं और कुछ अन्य तंत्र इसे बाद में एक्सेस/रिलीज़/डिलीक करने का प्रयास करते हैं।

जब भी मुझे EXC_BAD_ACCESS त्रुटि की रिपोर्ट मिलती है, तो मेरी पहली सिफारिश यह निर्धारित करने के लिए कोड के माध्यम से कदम उठाना है कि कौन सी रेखा इसे उत्पन्न कर रही है, और उसके बाद उस ऑब्जेक्ट को संदर्भित करने वाले किसी भी स्पष्ट [object release] कॉल की खोज करने के लिए। उनको एक-एक करके टिप्पणी करें कि आप कहां गलत हो गए हैं (और, ज़ाहिर है, टी सुनिश्चित करें वह ऑब्जेक्ट बाद में ठीक से जारी किया गया है)।

यदि रेखा आपको यह पता लगाने में मदद नहीं करती है कि कौन सी ऑब्जेक्ट समस्या का कारण बन रही है, तो अपने [object release] कॉलों को देखना शुरू करें, और सुनिश्चित करें कि आप दुर्घटना से कई बार ऑब्जेक्ट जारी नहीं कर रहे हैं, या रिलीज़ कर रहे हैं ऑब्जेक्ट्स जो आपके पास नहीं है।

यह ऑब्जेक्टिव-सी में release के बारे में एक अच्छा सामान्य दिशानिर्देश की ओर जाता है:

आप एक वस्तु के मालिक हैं (आवंटित या इसे बनाए रखने के लिए), तो आप उसे छोड़ दें। यदि आपके पास इसका स्वामित्व नहीं है (सुविधा विधि के माध्यम से आया है या किसी और को आवंटित किया गया है), तो आप इसे जारी नहीं करते हैं।

(वाया Memory Management with Objective C/Cocoa/iPhone है, जो भी कुछ अच्छे सुझाव दिए गए हैं।)

1

अंगूठे का सामान्य नियम है कि कुछ भी आप बनाते हैं, आप का प्रबंधन करने की जरूरत है (बनाए रखने/रिलीज) है। एनआईबी से बाहर आने वाली कुछ भी, आम तौर पर कोड में जारी नहीं की जानी चाहिए।

3

[सुपर डेलोक] को क्लास डेलोक विधि के अंतिम विवरण के रूप में रखें। जब आप सुपर क्लास को पहले हटा देते हैं तो आपको यह व्यवहार मिल जाएगा।

6

हालांकि यह अक्सर गलत प्रबंधन की स्मृति का परिणाम होता है, यह अन्य कारणों से हो सकता है (और NSZombieEnabled को चालू करने से पहले डीबग करना कठिन हो)। उदाहरण के लिए, यदि आप स्वरूप स्ट्रिंग में सही संख्या में तर्क प्रदान करने में विफल रहते हैं (यानी NSLog के साथ किसी अन्य समस्या को डीबग करते समय), तो आप सभी डिबगिंग तर्क सक्षम किए बिना भी कोई स्टैक ट्रेस नहीं कर सकते हैं। सौभाग्य से, आप एक्सडीकोड के भीतर जीडीबी का उपयोग restore the stack trace to a previous state पर कर सकते हैं।

जीडीबी कंसोल में आपको अपने प्रोग्राम को क्रैश करने वाले निर्देश को देखना चाहिए। असफल होने से पहले अंतिम सफल वापसी निर्देश का पता लगाएं।यह कुछ इस तरह दिखना चाहिए:

je 0x986cef35 <objc_msgSend+117> 

नोट हेक्स मान और निष्पादित GDB में निम्नलिखित:

set $eip = 0x986cef35 
stepi 
where 

आप चाहिए (उम्मीद) एक अधिक सूचनात्मक स्टैक ट्रेस अब है।

Source

+0

[लिंक] (http://www.mulle-kybernetik.com/weblog/2010/07/exc_bad_access_and_no_stack_tr.html) काम नहीं कर रहा है। यहां [अपडेटेड] है (http://www.mulle-kybernetik.com/weblog/2010/exc_bad_access_and_no_stack_tr.html) एक – BLC

1

कि उपर्युक्त कथन आप निब वस्तुओं नहीं जारी करना चाहिए एप्पल ने खण्डन किया है (ऊपर के लिंक के रूप में ही): here, जहां यह कहा गया है कि वस्तुओं जिसके लिए आप एक दुकान है dealloc में जारी की जानी चाहिए देखना , और यह भी कि आपको ऑब्जेक्ट संदर्भ को बाद में शून्य पर सेट करना सुनिश्चित करना चाहिए।

अस्वीकरण: मैं एक आईफोन प्रोग्रामिंग नौसिखिया हूं, हालांकि लंबे समय तक प्रोग्रामिंग कर रहा हूं।

2

कैमरून स्पिकर्ट का जवाब थोड़ा बहिष्कृत है, क्योंकि Xcode अब gdb के बजाय lldb का उपयोग करता है। स्रोत लेख का लिंक भी मर चुका है।

एक ही बात निम्नलिखित lldb कमांड के साथ नहीं बल्कि बस किया जा सकता है:

(lldb) thread backtrace 

यह वर्तमान थ्रेड के लिए bt दिखाएगा। आप धागा है जिसमें से आप bt प्राप्त करना चाहते हैं बदलना चाहते हैं, फ़्रेम का चयन करें और इस तरह से इसे पाने:

(lldb) thread list 
(lldb) thread select 2 
(lldb) thread backtrace 

आप कैमरून Spickert के जवाब का सही व्यवहार को दोहराने के लिए चाहते हैं, निम्न कमांड का उपयोग करें:

(lldb) expr unsigned int $eip = 0x1979c81d4 
(lldb) stepi 
(lldb) thread backtrace 

Source 1

Source 2

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