2009-07-31 10 views
9

मैं चाहता हूं कि मेरा आवेदन कभी बेवकूफ न हो। मुझे पता है कि कोड गुणवत्ता इसके लिए मूल समाधान है। लेकिन जब भी कुछ अप्रत्याशित बग होता है तब भी मुझे कभी भी क्रैश करने के लिए एक एप्लिकेशन की आवश्यकता नहीं होती है। यहां कोड है जिसे मैं आजमा देना चाहता हूं।आईफोन विकास: उद्देश्य-सी में अपवाद/एनएसईआरआर कैच कैसे करें?

-(void)testException 
{ 
    @try 
    { 
     NSString* str; 
     [str release]; 
    } 
    @catch(NSException* ex) 
    { 
     NSLog(@"Bug captured"); 
    } 
} 

मुझे पता है कि यह काम नहीं करता है। क्योंकि release कभी अपवाद नहीं उठाता है। यहां मेरे प्रश्न हैं:

  1. इस तरह के उद्देश्य तक कैसे पहुंचे, बग पकड़ा जाएगा, कोई दुर्घटना नहीं होगी?
  2. मुझे कैसे पता चलेगा कि कौन सी सिस्टम लाइब्रेरी अपवाद उठाएगी और इसलिए मैं कुछ कोड लिख सकता हूं और जानता हूं कि यह काम करता है?

यहाँ मैं

  • एक क्या पढ़ा है है। Cocoa
  • बी के लिए अपवाद प्रोग्रामिंग विषय। कोको

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

आप लोग/गैल्स (मैक प्रतिभा प्रोग्रामर) कैसे दुर्घटना मुक्त कार्यक्रम हुए? अपना अनुभव साझा करें।

उत्तर

3

आपके पास एक मुद्दा यह है कि स्ट्र को कभी शुरू नहीं किया गया है जिसका अर्थ है कि str शून्य हो सकता है (लेकिन इसकी गारंटी नहीं है)। यह निश्चित रूप से जंक को इंगित कर रहा है।

यदि आप अपने कोड से कदम उठाते हैं, तो मैं लगभग गारंटी दे सकता हूं कि आपकी रिलीज को शून्य पर बुलाया जा रहा है, जिसमें उद्देश्य-सी पूरी तरह से मान्य है।

कर इस प्रयास करें:

NSString *str = [[NSString alloc] initWithString:@"a string"]; 
[str release]; 
[str release]; 

रिहाई कॉलिंग एक वस्तु पुनःआवंटन नहीं करता है, यह केवल 1. द्वारा गिनती बनाए रखने के एक वस्तुओं को बनाए रखने जब गिनती 0 decrements,

[self dealloc]; 

स्वचालित रूप से कहा जाता है ।

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

आप क्या कर सकते हैं एनएसओब्जेक्ट में एक श्रेणी जोड़ना और डेलोक और रिलीज विधियों को लागू करना और पकड़ने की कोशिश करना आप वहां अपवाद हैं।

- (void)dealloc{ 

@try 
    { 
     [super dealloc]; 
    } 
@catch(NSException* ex) 
    { 
     NSLog(@"Bug captured"); 
    } 

} 



- (void)release{ 

    @try 
     { 
      [super release]; 
     } 
    @catch(NSException* ex) 
     { 
      NSLog(@"Bug captured"); 
     } 

    } 

अतिरिक्त बोनस है कि यह कोड अपने एप्लिकेशन में हर वस्तु के लिए मान्य होगा, क्योंकि यह NSObject पर एक वर्ग है।

हालांकि पूरा होने के लिए, यदि आप उन्हें स्मृति प्रबंधन नियमों का अभ्यास करते हैं, तो आप ठीक होंगे।

+0

आपके उत्तर के लिए धन्यवाद। आपका उत्तर मुझे मेमोरी प्रबंधन को बेहतर ढंग से समझने और उद्देश्य सी के बारे में अपना ज्ञान बढ़ाने में मदद करता है। हालांकि, मैंने कोड की कोशिश की है, वे कभी दुर्घटनाग्रस्त नहीं होते हैं (वे होना चाहिए, मैं 4 बार रिलीज करना चाहिए, यदि संदर्भ संभव हो तो संदर्भ संख्या 3 होनी चाहिए)। लेकिन कोई भी दुर्घटना नहीं हुई, कोई अपवाद फेंक नहीं गया। मुझे पता है कि यह कभी-कभी दुर्घटनाग्रस्त हो जाएगा। लेकिन कब नहीं पता। तो वापस बुनियादी, क्या दुर्घटना से बचने का कोई तरीका है? –

+0

बरकरार रखने के साथ चिंतित मत बनो। आपको इसे कभी भी जांचना नहीं चाहिए, ऐसा कभी नहीं होता है जो आपको लगता है कि यह विभिन्न कारणों से होना चाहिए। आपको एक समय में स्मृति प्रबंधन की एक विधि का ख्याल रखना चाहिए। कोको स्मृति प्रबंधन के लिए Stackoverflow और Google खोजें। आपकी मदद करने के लिए बहुत सारे संसाधन हैं। पहले सीखना मुश्किल हो सकता है, लेकिन अधिक स्वचालित हो जाता है। –

12

उद्देश्य-सी एक अप्रबंधित रनटाइम है; जो कोड आप संकलित करते हैं वह वर्चुअल मशीन की बजाय सीधे CPU पर चलता है। इसका मतलब है कि आपके पास पर्यवेक्षी परत नहीं है जो .NET VM या JVM में चलते समय हर संभव विफलता मोड को जाल कर सकती है। इसका लंबा और छोटा यह है कि एकमात्र तरीका यह है कि आप पूरी तरह से सुनिश्चित होने जा रहे हैं कि कोई प्रोग्राम क्रैश नहीं हो सकता है, बहुत सावधानी से कोड करना और बहुत अच्छी तरह से परीक्षण करना है। और फिर भी, आप निश्चित नहीं हैं, आप बस सोचते हैं कि आप हैं।

एक्सकोड का नवीनतम संस्करण क्लैंग स्थिर विश्लेषक (बिल्ड मेनू में 'बिल्ड और विश्लेषण' को एकीकृत करता है जो संभावित बग के कुछ वर्गों को पहचान सकता है - मुझे पूरा यकीन है कि यह आपके उदाहरण को उपरोक्त ध्वजांकित करेगा, उदाहरण के लिए) । लेकिन यहां कोई जादू बुलेट नहीं है; एकमात्र समाधान कड़ी मेहनत है।

4

टेस्ट टेस्ट टेस्ट टेस्ट टेस्ट

आप सभी दिन खर्च (जो व्यवहार में पाए जाते हैं कभी नहीं होगा) संभव अपवाद के लिए अपवाद हैंडलिंग कोड लिखने सकते हैं या आप पूरी तरह से परीक्षण स्वीट बना सकते हैं और केवल के लिए अपवाद संचालकों लिखने अभ्यास में होने वाली स्थितियां।

यही कारण है कि मैं लगभग अपवाद हैंडलर कभी नहीं लिखता। यदि आप अंतर्निहित मुद्दों को ठीक करते हैं जो अपवाद पैदा कर रहे हैं, तो आपको कुछ भी संभालने की आवश्यकता नहीं है।

बेशक, ऐसी परिस्थितियां हैं जहां यह सुनिश्चित नहीं किया जा सकता कि एक विधि कॉल अपवाद का कारण नहीं बनता है और आपको तैयार होने की आवश्यकता है, लेकिन @ try/@ catch ब्लॉक में सबकुछ लपेटना निश्चित रूप से समाधान नहीं है।

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