2011-12-13 13 views
6

मेरे एक दोस्त ने NSDictionary के साथ कुछ अजीब व्यवहार की खोज की, और मैं उत्सुक हूं कि ऐसा क्यों होता है। निम्नलिखित कोड पर विचार करें:यह उद्देश्य सी कॉल क्यों लटका हुआ है?

NSDictionary *dict = [[NSDictionary alloc] init]; 

// Oops, we can't mutate an NSDictionary 
[dict setObject:[[NSNull alloc] init] forKey:@"test"]; 
NSLog(@"Set"); 

कोड संकलन है कि " 'NSDictionary' ': forKey: setObject' का जवाब नहीं हो सकता है" पर एक चेतावनी पैदा करता है। यही कारण है कि सब कुछ ठीक है और अच्छा है, और यदि आप इसे वैसे भी चलाते हैं, तो आप कंसोल में इस उत्पादन मिल जाएगा:

- [__ NSCFDictionary setObject: forKey:]: विधि अपरिवर्तनीय वस्तु के लिए भेजा परिवर्तनशील

फिर से, आप वास्तव में क्या होने की उम्मीद करेंगे। हालांकि, इस बिंदु पर ऐप को क्रैश नहीं करता है या बिना किसी अपवाद के समाप्त हो जाता है। SetObject: forKey: विधि बस कभी वापस नहीं आती है, और ऐप लटकता प्रतीत होता है; निम्नलिखित NSLog कभी निष्पादित नहीं किया जाता है। यदि आप जीडीबी का उपयोग करके विधि में कदम उठाने की कोशिश करते हैं, तो डिबगिंग बस समाप्त होता है, लेकिन बिना किसी स्पष्ट त्रुटि संदेश के। ऐप चल रहा है, लेकिन डीबगर कोई संकेत नहीं देता है कि कोड में निष्पादन "अटक गया" कहां है।

यहां क्या हो रहा है? वास्तव में इस मामले में ऐप क्या कर रहा है, और यह एनएसआईएननल इंटरकेंसिस्टेंसी अपवाद या कुछ ऐसा क्यों नहीं है?

संपादित करें: उन लोगों के लिए, जिन्हें मैंने पूछा है, मैं ओएस एक्स शेर (10.7.2) पर एक्सकोड 4.1 चला रहा हूं, "ऐप्पल एलएलवीएम कंपाइलर 2.1" के साथ निर्माण कर रहा हूं। मैं एक्सकोड 4 में एक नई कोको परियोजना के साथ प्राप्त होने वाली सभी डिफ़ॉल्ट सेटिंग्स का उपयोग कर रहा हूं। मुझे इस कार्यक्रम को डीबग करने या बस इसे "रन" करने के बावजूद एक ही गैर-क्रैशिंग व्यवहार का अनुभव होता है। डीबग बिल्डिंग से रिलीज बिल्डिंग में बदलना कोई फर्क नहीं पड़ता। मैं फाइंडर में मैन्युअल रूप से .app फ़ाइल का पता लगा सकता हूं और एक्सकोड के बाहर इसे निष्पादित करने के लिए डबल क्लिक कर सकता हूं, और यह अभी भी क्रैश नहीं होता है।

+1

इसे डीबगर के तहत नहीं चलाने का प्रयास करें; मैं इसे मुश्किल दुर्घटनाओं पर शर्त लगाता हूं। मुझे लगता है कि डीबगर पर्यावरण में रनटाइम पर्यावरण पर विशेष रूप से अपवादों के बारे में कुछ अप्रत्याशित प्रभाव हो सकते हैं और जब आप उन्हें मारते हैं तो क्या होता है। –

+2

जब अपवाद फेंक दिया जाता है, अपवाद के बाद अगली पंक्ति अपवाद को पकड़ने के साथ नियंत्रण फिर से शुरू हो जाएगा। आपके उदाहरण में या तो डीबगर, या रनटाइम के आंत, अपवाद "पकड़ा"। किसी भी मामले में आप NSLog को -setObject के बाद होने की उम्मीद नहीं करेंगे: के लिए: अपवाद फेंक दिया। –

+0

@ विन्सेंटगेबल: सहमत है, अगर प्रोग्राम दुर्घटनाग्रस्त हो गया तो मैं कम से कम आश्चर्यचकित नहीं होगा कि एनएसएलओजी को नहीं बुलाया गया था। मुझे आश्चर्य है कि यह न तो दुर्घटनाग्रस्त हो जाता है और न ही अगली पंक्ति में आगे बढ़ता है। ऐसा लगता है कि इसे एक या दूसरे करना चाहिए। उन लोगों के लिए जिन्होंने मुझसे पूछा है, मैंने पर्यावरण के बारे में कुछ अतिरिक्त विवरणों के साथ प्रश्न अपडेट किया है। –

उत्तर

1

अपवाद ऐपकिट प्रोग्राम को क्रैश नहीं करते हैं। एनएसएप्लिकेशंस एक डिफ़ॉल्ट अपवाद हैंडलर स्थापित करता है जो आपके कोड को अपवादों को पकड़ता है। फिर आप सामान्य रूप से रनलोप में वापस जाते हैं।

बहुत से ऐप्स इस व्यवहार को प्रदर्शित करते हैं। यह अतुल्य खाली दृश्य/खिड़कियों का एक आम कारण है। यदि दृश्य को पूरा करने से पहले कोई अपवाद होता है, तो दृश्य खाली हो जाएगा, लेकिन ऐप क्रैश नहीं होगा। अपवाद केवल तभी क्रैश का कारण बनते हैं यदि आप जानबूझकर डिफ़ॉल्ट अपवाद हैंडलर को क्रैश करने के लिए बदलते हैं।

+0

का बहुत अधिक डुप्लिकेट धन्यवाद, यह ज्यादातर मेरे उत्तर देता है सवाल। एक बात जो मैं अभी भी उलझन में हूं, यही कारण है कि अपवाद पकड़े जाने के बाद मैं मुख्य ईवेंट लूप पर एप्लिकेशन रिटर्न नहीं देख सकता। या यह एक अलग धागे में होता है? मैं ऐपकिट की आंतरिक कार्यप्रणाली से परिचित नहीं हूं। –

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