2009-06-26 7 views
8

का उपयोग कर त्रुटियों की जांच के लिए सही संरचना मैं विभिन्न दिनचर्या को कोडिंग कर रहा हूं और मैं इसे साफ और रिफैक्टर रखने के लिए अपनी पूरी कोशिश कर रहा हूं।NSError

तरीके मैं बना रहा हूं इस कोड के लिए इसी तरह देखने के लिए शुरू कर रहे हैं:

-(IBAction)buttonPress:(id)sender { 
    // Create Document Shopping List with this document 
    [self doSomething:&error]; 

    if(error) { 
     [NSApp presentError:&error]; 
     return nil; 
    } 

    [self doSomethingElse:&error]; 

    if(error) { 
     [NSApp presentError:&error]; 
     return nil; 
    } 

    [self doYetSomethingElse:&error]; 

    if(error) { 
     [NSApp presentError:&error]; 
     return nil; 
    } 
} 

मैं NSError प्यार करता हूँ, लेकिन यह सब मेरी त्रुटियों से निपटने का एक बहुत अनाड़ी रास्ते की तरह लगता है।

कुछ विचार मैं वैकल्पिक तरीकों के बारे में लिया है:

क) त्रुटि जाँच तरीकों DoSomething, doSomethingElse आदि में बनाया जा सकता है, लेकिन फिर मैं बिना बटन प्रेस विधि बाहर निकलने के लिए सक्षम नहीं होगा वापसी मूल्य पर किसी प्रकार की जांच कर रहा है, जो मुझे एक समान संरचना में ले जाएगा।

बी) मैं एनएसईआरआरआर को मुख्य मूल्य के रूप में स्थापित कर सकता हूं, लेकिन इसके बारे में कुछ गहराई से गलत लगता है। मैं केवीओ के साथ दुर्व्यवहार की संभावनाओं से बहुत अवगत हूं, इसलिए मैं इसके बिना सब कुछ करने की कोशिश कर रहा हूं।

निश्चित रूप से मुझे यहां कुछ मूलभूत याद आ रही है? क्या कोई पैटर्न है जो मेरी मदद कर सकता है? या यह संरचना ठीक है?

+0

मैं पिछले 10 मिनट में प्राप्त अद्भुत प्रतिक्रिया से पूरी तरह से परेशान हूं! आपके उत्तरों के लिए बहुत बहुत धन्यवाद। बहुत, बहुत उपयोगी। –

उत्तर

11

मुझे लगता है कि यहां प्रस्तुत किए गए उत्तरों में से कोई भी ऐप्पल की अनुशंसित प्रथाओं को ध्यान में रख रहा है।

असल में आपको यह निर्धारित करने के लिए NSError ऑब्जेक्ट की जांच नहीं करनी चाहिए कि कोई समस्या है या नहीं। आप जांचते हैं कि विधि से लौटाए गए मान की जांच करके कोई समस्या हुई है जो सूचक को NSError पर पॉइंटर लेता है।

the Apple documentation से:

महत्वपूर्ण सफलता या विफलता विधि के रिटर्न मान ने संकेत दिया है। हालांकि कोको तरीकों कि परोक्ष रूप से में त्रुटि वस्तुओं लौट कोको त्रुटि डोमेन इस तरह की वस्तुओं वापस जाने के लिए गारंटी दी जाती है अगर विधि सीधे nil या NO वापस लौट कर विफलता को इंगित करता है, तो आप हमेशा जांच करनी चाहिए कि वापसी मान है nil या NO प्रयास करने से पहले NSError ऑब्जेक्ट के साथ कुछ भी करें।

+0

कुछ तरीकों जैसे SendAsynchronousRequest वापसी शून्य और केवल एक चीज जो आप कर सकते हैं वह एनएसईआरआरआर जांचना है। या क्या मैं कुछ न कुछ भूल रहा हूं? –

+2

उस स्थिति में आप अन्य पैरामीटर की जांच करें। यही है, NSURLResponse और NSData। –

0

नोट: जब मैंने इसे पोस्ट किया तो मुझे किसी भी मैकोज़/कोको अपवाद बहस से अनजान था। जब आप इस उत्तर पर विचार करते हैं तो कृपया इसे ध्यान में रखें।

इसके बजाय exceptions का उपयोग क्यों नहीं करें? यह आपको अपनी विधियों पर त्रुटि पैरामीटर के साथ बांटने की अनुमति देगा और आपकी त्रुटियों को एक ही स्थान पर संभाल देगा।

NSException* e = [NSException exceptionWithName:@"MyException" 
             reason:@"Something bad happened" 
             userInfo:nil]; 
@throw e; 
+3

मैक ओएस एक्स/कोको में प्रवाह नियंत्रण के अपवादों का उपयोग करने के बारे में एक सतत बहस है या नहीं। मैं व्यक्तिगत रूप से उस स्थिति को लेता हूं जो (अधिकांश) ऐप्पल लेता है, कोको में अपवाद असाधारण प्रोग्रामिंग त्रुटियों के लिए हैं, और इसलिए प्रवाह नियंत्रण के लिए उपयोग नहीं किया जाना चाहिए। – danielpunkass

+0

यह जानने में रुचि होगी कि यह क्यों चिह्नित किया गया था। मुझे क्या याद आया? – teabot

+2

आह, इसे @danielpunkass को साफ़ करने के लिए धन्यवाद - मैं जावा पृष्ठभूमि से हूं इसलिए इस तरह की बहस से अनजान उद्देश्य-सी में अपवादों का उपयोग करके खुशी से उपयोग कर रहा हूं। – teabot

1

मुझे लगता है कि असली सवाल कितना विवरण के स्तर को आप अपने त्रुटि हैंडलिंग में की जरूरत है:

-(IBAction)buttonPress:(id)sender { 
    // Create Document Shopping List with this document 
    @try { 
     [self doSomething]; 
     [self doSomethingElse]; 
     [self doYetSomethingElse]; 
    } @catch (NSException* e) { 
     [NSApp presentException:e]; 
    } 
    return nil; 
} 

आप निश्चित रूप से अपवाद फेंक के रूप में अपने doXXXX तरीकों के भीतर से आवश्यक आवश्यकता होगी। आपका कोड मौलिक रूप से सही है - लेकिन आप कम त्रुटियों की जांच करके चीजों को साफ कर सकते हैं, या एनएसईएक्सप्शन के साथ अपने उत्तर में वर्णित टीबोट जैसे कैच-ऑल दृष्टिकोण का उपयोग कर सकते हैं। बहुत सारे अंतर्निहित फ़ंक्शंस जो त्रुटियों को वापस करते हैं (जैसे NSFileManager के moveItemAtPath :) एक एनएसईआरआर ऑब्जेक्ट प्रदान करने के अलावा एक बूल लौटाते हैं - ताकि यदि आप एनएसईआरआर जानकारी की आवश्यकता नहीं है तो आप नेस्टेड का उपयोग भी कर सकते हैं।

सभी और सभी, वास्तव में ऐसा करने का कोई शानदार तरीका नहीं है। यदि आपका कोड लंबा है, तो केवीओ एक अच्छा समाधान हो सकता है। हालांकि, मैंने इस तरह की स्थिति के लिए कभी कोशिश नहीं की है।

+0

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

+1

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

+0

बहुत अच्छा बिंदु, माइक। मुझे विचार करने के लिए कुछ और देता है। केवल इसे पढ़ें, मैंने तुरंत इतनी पर्याप्त जांच नहीं की होनी चाहिए। –

2

आपके प्रश्न का सारांश यह है कि क्या आप अपने त्रुटि प्रबंधन में संरचनात्मक सुधार कर सकते हैं। मुझे लगता है कि, अनिवार्य रूप से घोंसले की अधिक परतों को पेश करके, या तो अलग-अलग तरीकों/कार्यों में अधिक कोड निकालने, या अपने उच्च स्तरीय नमूना विधि में घोंसले शुरू करके।

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

का उपयोग करने के इस विचार "का प्रचार या संभाल", मैं इस तरह अपने नमूना विधि को फिर से लिखने होगा:

-(IBAction)buttonPress:(id)sender { 

    // Create Document Shopping List with this document 
    [self doSomething:&error];  
    if(error == nil) { 
     [self doSomethingElse:&error]; 
     if (error == nil) { 
      [self doYetSomethingElse:&error]; 
     } 
    } 

    if(error) { 
     [NSApp presentError:&error]; 
    }  
} 

नोट एक विशेष विधि में बहुत अधिक नेस्टिंग शुरू करने के खिलाफ अच्छा तर्क देखते हैं कि। इस तरह के घोंसले को विधियों को निकालने के लिए अनिवार्य रूप से एक छोटा विकल्प है। उदाहरण के लिए, यह अधिक समझ में आ सकता है, "ऐसा कुछ:" खुद को कॉल करता है कुछ ऐसा: जो कॉल करता है YetSomethingElse: उदाहरण के लिए। यह कोड पर समान संरचना को लागू करेगा, लेकिन अगर तर्कसंगत रूप से अधिक रखरखाव योग्य होगा।

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

+0

एक उत्कृष्ट सुझाव के लिए धन्यवाद, डैनियल। मैं ऐसा करने से दूर शर्मिंदा हूं क्योंकि कोड पूर्ण नेस्टिंग को कम करने की सिफारिश करता है। मैंने कुछ दुःस्वप्न घोंसला बना दिया है .. और मेरे समय में बयान। और अगर मेरे पास 5 से अधिक कदम थे, तो मुझे लगता है कि यह बोझिल हो जाएगा। दूसरी तरफ, यदि मेरे पास 5 से अधिक कदम थे, तो मुझे लगता है कि यह एक चेतावनी संकेत होगा कि मेरे कोड को वैसे भी दोबारा सुधारने की आवश्यकता है। और यह विशिष्ट घोंसले अभी भी काफी पठनीय है और मेरे मूल की तुलना में बहुत साफ है, इसलिए मैं यही करूँगा। फिर से धन्यवाद! –

+1

खुशी है कि आपने जवाब की सराहना की। मैं कोड पूर्ण करने और घोंसले को कम करने के बारे में भी सोचता हूं, लेकिन मैंने इसे ऊपर तर्कित करने के तरीके को तर्कसंगत बनाया है, यह मानने के लिए कि न्यूनतम घोंसले केवल कोड के लिए एक शॉर्टेंड है जिसे परिस्थितियों के लिए कॉल करते समय किसी अन्य विधि या फ़ंक्शन में फ़ैक्टर किया जा सकता है। आम तौर पर, मुझे लगता है कि घोंसले वैकल्पिक, "रन-ऑन" फ़ंक्शन से बेहतर है ... – danielpunkass

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