2011-07-20 13 views
6

में डीबग सामान के साथ गड़बड़ी से बचें जब मैं कुछ लिखता हूं, आधा प्रयास स्पष्ट और संक्षिप्त डीबग आउटपुट जोड़ने में 0 गुना प्रयास करता है, या कार्यक्षमता जिसे कुछ डिबगिंग की आवश्यकता होती है उसे सक्षम/अक्षम किया जा सकता है।कोड

डिबग कार्यक्षमता का एक उदाहरण एक डाउनलोडर वर्ग जहां मैं एक #define जो इसे "नाटक" फाइल डाउनलोड करने के लिए और बस मुझे वापस एक मैं पहले से ही है हाथ में आता है पर बारी कर सकते हैं। इस तरह से मैं यह देखने के लिए परीक्षण कर सकता हूं कि जब उपयोगकर्ता किसी फ़ाइल को डाउनलोड करता है, तो नेटवर्क को भौतिक रूप से फ़ाइल को हर बार पकड़ने के लिए इंतजार किए बिना क्या होता है। यह करने के लिए बहुत अच्छी कार्यक्षमता है, लेकिन कोड #ifdefs के साथ गड़बड़ हो जाता है।

मैं अंत में की तरह

// #define DEBUG_FOOMODULE_FOO 
// #define DEBUG_BARMODULE_THINGAMAJIG 
// ... 

जो सामान मैं को देखने के लिए चाहते हैं के लिए uncommented हैं #define एस के एक समूह के साथ खत्म। कोड स्वयं

- (void)something 
{ 
    #ifdef DEBUG_FOOMODULE_FOO 
    DebugLog(@"something [x = %@]", x); 
    #endif 
    // ... 
    #ifdef DEBUG_FOOMODULE_MOO 
    // etc 
} 

यह कोड लिखने/बनाए रखने के लिए बहुत अच्छा काम करता है, लेकिन यह कोड की उपस्थिति के लिए कुछ भी नहीं करता है।

लोग कैसे लंबे समय तक लंबी अवधि के डीबग "सामान" को आसानी से लिखते हैं?

नोट: मैं केवल एनएसएलॉगिंग के बारे में बात नहीं कर रहा हूं ... मैं उपरोक्त डाउनलोड-डाउनलोड जैसी चीजों के बारे में भी बात कर रहा हूं।

+0

उत्सुक: क्या रिलीज निर्माण में 'एनएसएलओजी' बयान छोड़ने में कोई समस्या है? क्या यह प्रदर्शन को नुकसान पहुंचाता है, डिवाइस लॉग भरता है, या अन्यथा अवांछनीय परिणाम प्रदान करता है? –

+0

ऐप्पल का उल्लेख है कि इसे जारी करते समय आपको अपने कोड से NSLog प्रविष्टियों को हटा देना चाहिए, इसलिए मुझे लगता है कि यह करता है, हां। (मुझे वास्तव में यह नहीं मिल रहा है, लेकिन मैं लगभग निश्चित हूं कि मैंने इसे डेवलपर.पple.com पर कहीं पढ़ा है जब मैंने कोडिंग शुरू की थी।) – Kalle

+0

मुझे विश्वास है कि मुझे कहीं भी पढ़ना याद है। शायद एक बुरा विचार नहीं है। शायद ऐप का अगला संस्करण मैं मैक्रो और खोज/प्रतिस्थापन जोड़ूंगा। –

उत्तर

2

मैं अपने खुद के लिखने से पहले कई पुस्तकालयों पढ़ सकते हैं और दो दृष्टिकोण देखा: मैक्रो + सी कार्य (NSLogger) या मैक्रो + सिंगलटन (GTMLogger, Cocoa Lumberjack)।

मै मैक्रो + सिंगलटन का उपयोग करके अपने बेवकूफ कार्यान्वयन here लिखा। मैं रनटाइम के दौरान ऐसा करता हूं:

[Logger singleton].logThreshold = kDebug; 
trace(@"hi %@",@"world); // won't show 
debug(@"hi %@",@"world); 

आप लॉग स्तर के बजाय पैकेज के लिए भी ऐसा ही कर सकते हैं। अगर मैं इसे चाहता हूं, तो मैं # डिफाईन्स बदलता हूं।

#define trace(args...) [[Logger singleton] debugWithLevel:kTrace line:__LINE__ funcName:__PRETTY_FUNCTION__ message:args]; 

if (level>=logThreshold){ 
    // ... 
} 

आप कुछ लकड़हारा में और अधिक परिष्कृत देखो चाहते हैं, यह कुछ कक्षाओं के लिए प्रवेश करने टॉगल करने के लिए एक रजिस्टर वर्ग की सुविधा है: यहाँ कोड शामिल है।

+0

दिलचस्प। निश्चित रूप से उनको देखेंगे, धन्यवाद! – Kalle

+0

थोड़ा सा देखा। मुझे लगता है कि सबसे बड़ी समस्या यह है कि कभी-कभी मैं उन # डिफाईन्स के अंदर डिबगिंग उद्देश्यों के लिए विशेष कोड भी शामिल करता हूं। मुझे एहसास हो रहा है कि यह शायद एक बुरा दृष्टिकोण है चाहे आप इसे कैसे करें ...: / – Kalle

0

आपके मामले के लिए, अलग-अलग लॉगिंग मैक्रोज़ हो सकते हैं, MooLog और FooLog कहें, कि सभी सशर्त रूप से अलग झंडे के आधार पर संकलित करें।

#ifdef DEBUG_FOO 
# define FooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); 
#else 
# define FooLog(...) 
#endif 

#ifdef DEBUG_MOO 
# define MooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); 
#else 
# define MooLog(...) 
#endif 

आपका जटिल तर्क हर जगह अब यह हो जाता है:

- (void)something 
{ 
    // This only gets logged if the "DEBUG_FOO" flag is set. 
    FooLog(@"something [x = %@]", x); 
    // This only gets logged if the "DEBUG_MOO" flag is set. 
    MooLog(@"Something else [y = %@]", y); 
} 
+0

ठीक है, मैंने इसे उपरोक्त कोड में NSLog को सरल बना दिया है, लेकिन मैं पहले से ही कोड का उपयोग कर रहा हूं जो ऐसा करता है। मैं जो पूछ रहा हूं वह यह है कि आप "डीबग मॉड्यूल" को सक्षम/अक्षम कर सकते हैं। मुझे लगता है कि मैं # मॉड्यूल पर कटौती करने के लिए उन मॉड्यूल में से प्रत्येक के लिए # डिफाईन फ़ंक्शंस का एक गुच्छा लिख ​​सकता हूं लेकिन ऐसा करने का कोई बेहतर तरीका नहीं है? : | – Kalle

1

दो कार्य होने के बाद और फिर उन्हें रन-टाइम पर उचित रूप से चुनें या जब संकलन मेरे लिए एक स्वच्छ दृष्टिकोण की तरह लगता है। इससे अलग-अलग कार्यान्वयन के अलावा एक ही कार्य के साथ एक download.c और एक download_debug.c फ़ाइल संभव हो सकती है। फिर यदि आप -DDEBUG के साथ बना रहे हैं या नहीं, तो उपयुक्त के साथ लिंक करें।

अन्यथा, फंक्शन पॉइंटर्स का उपयोग करके रन-टाइम चयन कार्यों के लिए भी काम करता है।

यदि आप अपने कार्यों में डीबग कोड डालने का आग्रह करते हैं, तो आप अपने आप को गड़बड़ी के लिए बहुत अधिक स्थापित कर रहे हैं :) लेकिन, आप निश्चित रूप से उन स्निपेट को अलग-अलग कार्यों में तोड़ सकते हैं और फिर उपरोक्त (या उन्हें बना सकते हैं) डीएलओजी उदाहरण में नो-ऑप्स)।