वास्तव में NSAssert का क्या मतलब है?


155

मुझे यह पूछना है, क्योंकि: केवल एक चीज जिसे मैं पहचानता हूं, वह यह है कि यदि दावा विफल हो जाता है, तो ऐप क्रैश हो जाता है। क्या यही कारण है कि NSAssert का उपयोग क्यों किया जाता है? या इससे और क्या फायदा है? और क्या यह सही है कि मैं किसी भी धारणा के ऊपर एक NSAssert डालूं, जो एक कोड में एक फ़ंक्शन की तरह है, जिसे कभी भी -1 को परम के रूप में प्राप्त नहीं करना चाहिए, लेकिन -0.9 या -1.1 हो सकता है?

जवाबों:


300

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


9
आपको रिलीज़ के लिए NSAssert लेना चाहिए। ऐसा करने के लिए एक संकलन-समय ध्वज है।
बैरी वार्क सेप

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

18
ध्यान दें कि XCode 4 में रिलीज़ कॉन्फ़िगरेशन में डिफ़ॉल्ट रूप से परिभाषित NS_BLOCK_ASSERTIONS हैं। मुझे लगता है कि यदि आप नहीं बदलते हैं कि आपके जारी किए गए कोड में NSAssert: s नहीं होगा।
जॉनी

16
अगर मैं सही ढंग से समझूं, तो उन्हें (रिलीज संस्करण पर) छोड़ने का क्या मतलब है? यदि एक स्टेटमेंट के साथ NSAssert को प्रतिस्थापित नहीं किया जाता है, और यदि (कुछ भयानक होता है), तो उपयोगकर्ता को सूचित करें (या कुछ ऐसा करें जो आपके नियंत्रण में है), और न कि केवल छोड़ दिया / क्रैश करें और उपयोगकर्ता को यह सोचकर छोड़ दें कि क्या हुआ ... या क्या मैं कुछ भूल रहा हूँ?
Gik

11
यह प्रत्येक असाधारण मामले के रास्ते पर जाने के लिए डेवलपर समय की बर्बादी है जो सामान्य परिस्थितियों में बिल्कुल भी नहीं होना चाहिए। इसमें उपयोगकर्ता को उनमें से प्रत्येक के लिए सूचित करने और / या ऐप को किसी भी घटना के बाद अपेक्षित तरीके से आगे बढ़ाने के लिए उचित तरीके से सोचने के तरीके शामिल हैं। अधिक व्यावहारिक दृष्टिकोण ऐप को क्रैश करना और क्रैश रिपोर्ट से मिले बग को ठीक करना और एक नया संस्करण जारी करना है। यह कहने के बाद, यह सुनिश्चित करना महत्वपूर्ण है कि ऐसी किसी भी स्थिति में डेटा हानि न हो। यह सुनिश्चित किया जाना है, लेकिन यह बहुत कम काम है।
trss

20

मैं वास्तव में NSAssert से बात नहीं कर सकता, लेकिन मुझे लगता है कि यह C के मुखर () के समान काम करता है।

आपके कोड में शब्दार्थ अनुबंध लागू करने के लिए assert () का उपयोग किया जाता है। इसका क्या मतलब है, आप पूछें?

ठीक है, यह ऐसा है जैसा आपने कहा था: यदि आपके पास एक फ़ंक्शन है जिसे कभी भी -1 प्राप्त नहीं करना चाहिए, तो आप मुखर () लागू कर सकते हैं:

शून्य gimme_positive_ints (int i) {
  मुखर (i> 0);
}

और अब आपको एरर लॉग (या STDERR) में ऐसा कुछ दिखाई देगा:

दावा i> 0 विफल: फ़ाइल example.c, पंक्ति 2

इसलिए न केवल संभावित खराब इनपुट के खिलाफ यह सुरक्षित-गार्ड है, बल्कि यह उन्हें एक उपयोगी, मानक तरीके से लॉग करता है।

ओह, और कम से कम C मुखर () में एक मैक्रो था, इसलिए आप अपने रिलीज़ कोड में नो-ऑप के रूप में मुखर () को फिर से परिभाषित कर सकते थे। मुझे नहीं पता कि अगर NSAssert (या यहां तक ​​कि किसी भी अधिक) के साथ मामला है, लेकिन यह उन जांचों को संकलित करने के लिए बहुत उपयोगी था।


2
हां, NSAssert एक मैक्रो भी है।
मार्टिन विकमैन

18

NSAssertआपको एप को क्रैश करने से ज्यादा देता है। यह आपको वर्ग, विधि और वह रेखा बताता है जहां अभिकथन हुआ। NS_BLOCK_ASSERTIONS का उपयोग करके सभी कथनों को आसानी से निष्क्रिय किया जा सकता है। इस प्रकार यह डिबगिंग के लिए अधिक उपयुक्त बनाता है। दूसरी ओर, NSExceptionकेवल फेंकने से ऐप क्रैश हो जाता है। यह अपवाद के स्थान के बारे में भी नहीं बताता है, और न ही इसे इतना ही अक्षम किया जा सकता है। नीचे दिए गए चित्रों में अंतर देखें।

एप्लिकेशन क्रैश हो जाता है क्योंकि एक जोर भी एक अपवाद उठाता है, जैसा कि NSAssert प्रलेखन राज्यों में है:

जब आह्वान किया जाता है, एक जोरदार हैंडलर एक त्रुटि संदेश प्रिंट करता है जिसमें विधि और वर्ग नाम (या फ़ंक्शन नाम) शामिल होते हैं। यह तब एक NSInternalInconsistencyException अपवाद उठाता है।

NSAssert:

एक जोर के बाद लॉग

NSException:

एक अपवाद के बाद लॉग


एक NSExceptionउत्पादन यह के माध्यम से रिटर्न अनुकूलित करने के लिए अवसर के बहुत सारे प्रदान करता है reasonऔर userInfoमानकों। ऐसा कोई कारण नहीं है कि आप डिबगिंग के साथ सहायता करने के लिए वर्ग का नाम, चयनकर्ता, पंक्ति की जानकारी और कुछ और नहीं जोड़ सकते हैं। IMHO, आप NSAssertविकास के दौरान डिबगिंग उद्देश्यों के लिए उपयोग करते हैं लेकिन उन्हें जहाज में अक्षम कर देते हैं; NSExceptionयदि आप शिपिंग कोड में दावा छोड़ना चाहते हैं तो आप फेंक देते हैं।
markeissler

17

ऊपर सभी ने जो कहा, उसके अलावा NSAssert()(सी के विपरीत assert()) का डिफ़ॉल्ट व्यवहार एक अपवाद को फेंकना है, जिसे आप पकड़ सकते हैं और संभाल सकते हैं। उदाहरण के लिए, Xcode यह करता है।


क्या इस बारे में अधिक है कि हम अपवाद को कैसे पकड़ और संभाल सकते हैं?
गॉन

1
कोको में अपवाद "वास्तविक और सुगम" नहीं हैं। यदि नियंत्रण कॉल ट्री में कहीं भी एक ऐप्पल फ़ंक्शन से गुजरता है, तो व्यवहार अपरिभाषित है। अपवाद विशुद्ध रूप से त्रुटि रिपोर्टिंग (उर्फ, क्रिटिसिज्म, आदि) के लिए हैं, जावा में सामान्य उपयोग के लिए नहीं।
माइकल

9

बस स्पष्ट करने के लिए, जैसा कि किसी ने उल्लेख किया है, लेकिन पूरी तरह से नहीं बताया गया है, कस्टम कोड बनाने (बजाय इफ़्स और खराब डेटा के लिए एक अपवाद को बढ़ाने के बजाय) का उपयोग करने और उपयोग करने का कारण है, यह दावा किया जाता है कि उत्पादन अनुप्रयोगों के लिए एसोउल्स को अक्षम किया जाना चाहिए।

विकासशील और डिबगिंग करते समय, त्रुटियों को पकड़ने के लिए आपके लिए ऐसर्स सक्षम होते हैं। जब एक असत्य के रूप में मूल्यांकन किया जाता है तो कार्यक्रम रुक जाएगा। लेकिन, जब उत्पादन के लिए संकलित किया जाता है, तो संकलक अभिकथन कोड को छोड़ देता है और वास्तव में आपके कार्यक्रम को तेजी से बनाता है। तब तक, उम्मीद है, आपने सभी कीड़े तय कर लिए हैं। यदि आपके कार्यक्रम में अभी भी बग हैं, तो उत्पादन के दौरान (जब दावे अक्षम होते हैं और कार्यक्रम "जोर देने पर रुक जाता है"), तो आपका कार्यक्रम संभवतः किसी अन्य बिंदु पर दुर्घटनाग्रस्त हो जाएगा।

NSAssert की मदद से: "यदि पूर्वप्रक्रमक मैक्रो NS_BLOCK_ASSERTIONS को परिभाषित किया गया है, तो दावे अक्षम हैं।" इसलिए, बस अपने वितरण लक्ष्य [केवल] में मैक्रो डालें।


6

NSAssert(और इसके stdlib समकक्ष assert) विकास के दौरान प्रोग्रामिंग त्रुटियों का पता लगाने के लिए हैं। आपको कभी भी ऐसा दावा नहीं करना चाहिए जो उत्पादन (जारी) अनुप्रयोग में विफल हो। इसलिए आप यह दावा कर सकते हैं कि आप कभी भी ऋणात्मक संख्या को ऐसी विधि से पारित नहीं करेंगे जिसके लिए सकारात्मक तर्क की आवश्यकता हो। यदि परीक्षण के दौरान दावा कभी विफल हो जाता है, तो आपके पास एक बग है। यदि, हालांकि, पास किया गया मान उपयोगकर्ता द्वारा दर्ज किया गया है, तो आपको उत्पादन में दावे पर भरोसा करने के बजाय इनपुट का उचित सत्यापन करने की आवश्यकता है (आप रिलीज के लिए एक #define सेट कर सकते हैं जो अक्षम बनाता है NSAssert*


2
+1 क्योंकि आपका जवाब मेरे लिए सबसे ज्यादा मायने रखता है! NSAssert का उपयोग करना और अधिक समझ में आता है यदि इसके विकास के उपयोग के लिए, रिलीज के बाद नहीं। मान दर्ज करने वाले उपयोगकर्ता को UI त्रुटि के बाद पालन किया जाना चाहिए, न कि NSAssert अनुप्रयोग को क्रैश करने के लिए। कोहरा छंट चुका है!
pnizzle

3

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

संक्षिप्त उत्तर: वे लागू करते हैं कि आपका कोड केवल इरादा के रूप में उपयोग किया जाता है।


3

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

अनुबंध द्वारा अभिकथन और डिजाइन के विषय में अधिक जानकारी नीचे पाई जा सकती है:

अभिकथन (सॉफ्टवेयर विकास)

अनुबंध द्वारा डिजाइन

निबंध के साथ प्रोग्रामिंग

अनुबंध द्वारा डिजाइन, उदाहरण के लिए [पेपरबैक]


2

अपने प्रश्न का पूरी तरह से उत्तर देने के लिए, डिबगिंग में सहायता करने के लिए किसी भी प्रकार के मुखर का बिंदु है। अपने स्रोत पर त्रुटियों को पकड़ना अधिक मूल्यवान है, फिर क्रैश होने पर उन्हें डीबगर में पकड़ना।

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


-3

NSAssertस्थिति से मेल खाने पर ऐप क्रैश करें। यदि इस शर्त के साथ मेल नहीं खाते हैं तो अगले कथन निष्पादित होंगे। नीचे दिए गए EX को देखें:

मैं सिर्फ यह परीक्षण करने के लिए एक ऐप बनाता हूं कि कार्य क्या NSAssertहै:

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self testingFunction:2];
}

-(void)testingFunction: (int)anNum{
    // if anNum < 2 -> the app will crash
    // and the NSLog statement will not execute
    // that mean you cannot see the string: "This statement will execute when anNum < 2"
    // into the log console window of Xcode
    NSAssert(anNum >= 2, @"number you enter less than 2");
    // If anNum >= 2 -> the app will not crash and the below 
    // statement will execute
    NSLog(@"This statement will execute when anNum < 2");
}

मेरे कोड में ऐप क्रैश नहीं होगा। और टेस्ट केस है:

  • anNum > = 2 -> ऐप क्रैश नहीं होगा और आप लॉग स्ट्रिंग देख सकते हैं: "यह स्टेटमेंट तब निष्पादित होगा जब कोई नोट <2" आउटपूट लॉग कंसोल विंडो में
  • anNum <2 -> ऐप क्रैश हो जाएगा और आप लॉग स्ट्रिंग नहीं देख सकते हैं: "यह स्टेटमेंट तब निष्पादित होगा जब anNum <2"

1
आप इसे दूसरे तरीके से प्राप्त कर चुके हैं। "एनएसएसेटर स्थिति के साथ मेल खाने पर ऐप क्रैश कर देता है। यदि स्थिति के साथ मेल नहीं खाता है तो अगले बयान निष्पादित होंगे"। यदि यह शर्त से मेल नहीं खाता है, तो NSAssert ऐप को क्रैश कर देता है, और यदि यह शर्त से मेल खाता है, तो सामान्य रूप से निष्पादित करें।
जो ताम

ऐप क्रैश होने और संदेश को तब लॉग करता है जब यह शर्त पूरी नहीं करता है अन्यथा यह आगे निष्पादित होता है।
प्रवीण एस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.