2011-02-15 17 views
78

कोको में, मुझे एनएसएएसएसर्ट, एनएसईएक्सप्शन, एनएसईआरआरआर का उपयोग कब करना चाहिए?उद्देश्य-सी: दावा बनाम अपवाद बनाम त्रुटि

यहाँ मैं क्या सोच रहा है या नहीं:

NSAssert - किसी भी ग्राहक दोहरी जांच नियमों, परंपराओं, मान्यताओं, या पूर्व की स्थिति और बाद की स्थिति के लिए प्रोग्रामर अपने फायदे के लिए इस्तेमाल किया कार्यक्रम बनाते समय?

एनएसईएक्सप्शन - लाइब्रेरी का उपयोग करने वाले अन्य प्रोग्रामर के लाभ के लिए एक थर्ड-पार्टी लाइब्रेरी बनाते समय, ताकि वे तुरंत जान सकें कि इनपुट कब अमान्य है?

एनएसईआरआर - फ़ाइल, डेटाबेस या वेब सेवा जैसे डेटा प्राप्त करने के लिए बाहरी सिस्टम के साथ इंटरफेसिंग करते समय मुझे परिणाम देने की गारंटी नहीं है?

उत्तर

98

एक एनएसएएसएसर्ट विफल होने पर अपवाद फेंक देगा। इसलिए एनएसएएसएसर्ट लिखने के लिए संक्षिप्त और आसान तरीका है और आपके कोड में आपके द्वारा किए गए किसी भी अनुमान को जांचना है। यह (मेरी राय में) अपवादों का एक विकल्प नहीं है, बस एक शॉर्टकट। यदि कोई दावा विफल रहता है तो आपके कोड में कुछ गलत हो गया है और कार्यक्रम जारी नहीं होना चाहिए।

ध्यान देने योग्य एक बात यह है कि एनएसएएसएसर्ट को रिलीज बिल्ड में आपके कोड में संकलित नहीं किया जाएगा, इसलिए इसका उपयोग आम तौर पर विकास के दौरान स्वच्छता जांच के लिए किया जाता है। मैं वास्तव में एक कस्टम जोर मैक्रो का उपयोग करता हूं जो हमेशा सक्रिय होता है।

बार आप अपने खुद के NSException@throw होता है जब आप निश्चित रूप से एक रिलीज के निर्माण में यह चाहते हैं, और सार्वजनिक पुस्तकालयों/इंटरफ़ेस जैसी चीजों में जब कुछ तर्क अमान्य हैं या आप गलत तरीके से बुलाया गया है। ध्यान दें कि यह वास्तव में मानक अभ्यास नहीं है @catch अपवाद और अपना आवेदन जारी रखना जारी रखें। यदि आप ऐप्पल के कुछ मानक पुस्तकालयों (उदाहरण के लिए कोर डेटा) के साथ कोशिश करते हैं तो बुरी चीजें हो सकती हैं।एक जोर के समान, यदि कोई अपवाद फेंक दिया जाता है तो ऐप को आम तौर पर काफी जल्दी समाप्त करना चाहिए क्योंकि इसका मतलब है कि कहीं प्रोग्रामिंग त्रुटि है।

एनएसईआरआरओआर आपके पुस्तकालयों/इंटरफेस में उन त्रुटियों के लिए उपयोग किया जाना चाहिए जो प्रोग्रामिंग त्रुटियां नहीं हैं, और इसे पुनर्प्राप्त किया जा सकता है। आप कॉलर को जानकारी/त्रुटि कोड प्रदान कर सकते हैं और वे त्रुटि को साफ़ रूप से संभाल सकते हैं, उपयोगकर्ता को उचित होने पर चेतावनी दे सकते हैं, और निष्पादन जारी रख सकते हैं। यह आमतौर पर फाइल-न पाए गए त्रुटि या कुछ अन्य गैर-घातक त्रुटि जैसी चीजों के लिए होगा।

+14

इसे अधिक दृढ़ता से रखने के लिए, एक ** NSException ** का उपयोग पुनर्प्राप्ति योग्य त्रुटि को इंगित करने के लिए नहीं किया जाना चाहिए। – bbum

+25

दूसरे शब्दों में: Obj-C का NSException == जावा की त्रुटि वर्ग, और ओब्जे-सी का एनएसईआरआरआर == जावा की अपवाद कक्षा। शब्दों में निरंतरता के लिए हुरेय! – Tustin2121

+2

असल में, एनएसएसएसएसएसर्ट को आपके कोड में संकलित किया जाएगा यदि आप अपनी प्रीकंपील्ड उपसर्ग फ़ाइलों में NS_BLOCK_ASSERTIONS नहीं जोड़ते हैं। नीचे [उत्तर] (http://stackoverflow.com/a/25660769/1764735) पढ़ें (अभी प्रशंसा करने के लिए 50 प्राप्त करें :) – likid1412

1

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

दावा आमतौर पर परीक्षण में उपयोग किया जाता है, और AFAIK को दूसरों की तरह सामान्य त्रुटि-प्रबंधन तंत्र के रूप में उपयोग नहीं किया जाता है।

+0

दावे अपरिवर्तनशीलताओं लागू करने के लिए इस्तेमाल किया जा सकता। उदाहरण के लिए, 'NSParameterAssert (someParam! = Nil); 'invariant को लागू करेगा कि निर्दिष्ट पैरामीटर शून्य नहीं होना चाहिए। –

+0

@Kevin बेलार्ड: इस प्रकार के दावे सामान्य रूप से रिलीज बनाता से बाहर परिभाषित कर रहे हैं, या कम से कम वे पिछले मैं जाँच की थी, इसलिए है कि मैं ने कहा कि वे एक सामान्य त्रुटि हैंडलिंग तंत्र नहीं हैं। – Chuck

+1

वे हो सकते हैं, लेकिन वे डिफ़ॉल्ट रूप से छोड़े नहीं जाते हैं। उस व्यवहार को पाने के लिए आपको एक बिल्ड सेटिंग बदलनी होगी। –

3

कोको में सम्मेलन यह है कि एक अपवाद प्रोग्रामर त्रुटि इंगित करता है। फ्रेमवर्क कोड समेत बहुत सारे कोड को अपवाद फेंकने के बाद ठीक से काम करने के लिए डिज़ाइन नहीं किया गया है।

किसी भी प्रकार की त्रुटि जिसे पुनर्प्राप्त करने योग्य होना चाहिए NSError द्वारा दर्शाया गया है। उपयोगकर्ता को NSError एस प्रस्तुत करने के लिए एक प्रणाली भी है। जैसा कि आप कहते हैं, यह ज्यादातर बाह्य संसाधनों के लिए उपयोगी है।

संकल्पनात्मक रूप से, एक दावा एक बयान है कि दिया गया भविष्य हमेशा सत्य का मूल्यांकन करता है; यदि ऐसा नहीं होता है, तो प्रोग्राम टूटा हुआ है। जबकि इसके व्यवहार को संशोधित किया जा सकता है, NSAssert परिवार डिफ़ॉल्ट रूप से NSInternalInconsistencyException एस (रिलीज बिल्ड में उन्हें बंद करने के विकल्प के साथ) फेंकने का एक सुविधाजनक तरीका है।

2

संपादित करें: Xcode 4.2 में, assertions are turned off by default for release builds,

अब NSAssert एक रिलीज में अपने कोड में संकलित नहीं किया जाएगा निर्माण, लेकिन आप का निर्माण सेटिंग में इसे बदल सकते हैं


@Mike वेलर , आपके उत्तर में एक गलत है। नोट करने के लिए

एक बात है कि NSAssert एक रिलीज निर्माण में अपने कोड में संकलित नहीं किया जाएगा, तो यह आम तौर पर विवेक के विकास के दौरान की जाँच के लिए प्रयोग किया जाता है।

वास्तव में, NSAssert अपने कोड में संकलित किया जाएगा अगर आप अपने precompiled उपसर्ग फाइलों में NS_BLOCK_ASSERTIONS न जोड़ें।

तकनीकी नोट TN2190 में हम पा सकते हैं:

मैक्रो NDEBUG तरह बंद करने के लिए फाउंडेशन के NSAssert अपने precompiled उपसर्ग फ़ाइलों के लिए निर्दिष्ट करने के लिए महत्वपूर्ण हैं सी ज़ोर या NS_BLOCK_ASSERTIONS बंद करने के लिए

या आप यह एक पढ़ सकते हैं: How to know if NSAssert is disabled in release builds?

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