IPhone में उद्देश्य-सी के साथ NSLog विधि का नाम


153

वर्तमान में, हम वर्ग नाम और लॉग के स्रोत लाइन नंबर का प्रिंट आउट करने के लिए एक विस्तारित लॉग तंत्र को परिभाषित कर रहे हैं।

#define NCLog(s, ...) NSLog(@"<%@:%d> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \
    __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__])

उदाहरण के लिए, जब मैं NCLog (@ "हैलो वर्ल्ड") कहता हूं; उत्पादन होगा:

<ApplicationDelegate:10>Hello world

अब मैं भी इस तरह की विधि का नाम देना चाहता हूं:

<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world

इसलिए, इससे हमारी डिबगिंग आसान हो जाएगी जब हम जान सकते हैं कि किस विधि को बुलाया जा रहा है। मुझे पता है कि हमारे पास Xcode डिबगर भी है, लेकिन कभी-कभी, मैं लॉग आउट करके भी डीबगिंग करना चाहता हूं।


अपने पिछले iPhoneप्रोजेक्ट में, मैंने वास्तव में मैन्युअल रूप से ऐसा किया था। इसका जवाब देखना अच्छा लगेगा।
याकूब Relkin

संभावित डुप्लिकेट: stackoverflow.com/questions/969130/…
erkanyildiz

जवाबों:


261
print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C

स्विफ्ट 3 और इसके बाद के संस्करण

print(#function)

120
NSLog(@"%@", NSStringFromSelector(_cmd))यदि आप उपयोग करने जा रहे हैं तो आपको वास्तव में उपयोग करना चाहिए _cmd, क्योंकि AFAIK Apple एक _cmdप्रकार का घोषित करता है SEL, सी-स्ट्रिंग नहीं। सिर्फ इसलिए कि इसे सी-स्ट्रिंग (मैक ओएस एक्स और आईफोन ओएस के वर्तमान संस्करणों के रूप में) के रूप में लागू किया जाना है, इसका मतलब यह नहीं है कि आपको इसे इस तरह से उपयोग करना चाहिए, क्योंकि एप्पल इसे ओएस अपडेट में बदल सकता है।
निक फोर्ज

5
हां, NSStringFromSelector अधिक सही उत्तर है। मैं कभी भी, लेकिन डिबग कोड के लिए सी स्ट्रिंग के रूप में _cmd का उपयोग नहीं करता।
10:10

वाह, पॉइंटर असंगतता के बारे में शिकायत करता है, लेकिन यह काम करता है ... तो _cmd (प्रकार: SEL) वास्तव में एक चर * है?
निकोलस मिआरी

3
विधि कॉल [self doSomething:arg1 somethingElse:arg2]सी फ़ंक्शन कॉल में परिवर्तित हो जाते हैं objc_msgSend(self, "doSomething:somethingElse:, arg1, arg2);। दूसरा पैरामीटर objc_msgSend()लेता है एक char*। याद रखें कि क्योंकि ऑब्जेक्टिव-सी रनटाइम डायनेमिक है, यह वास्तव में लुकअप टेबल का उपयोग करके यह पता लगाने के लिए है कि लोन टेबल में स्ट्रिंग्स के रूप में विधियों का प्रतिनिधित्व करने के लिए कौन सी कक्षा में इतनी चार * कॉल की जाती है।
जैक लॉरेंस

1
स्विफ्ट 2.2 के लिए उपयोग करना चाहिएprint("\(#function)")
जेक लिन

161

अपने प्रश्न का तकनीकी रूप से उत्तर देने के लिए, आप चाहते हैं:

NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);

या आप भी कर सकते हैं:

NSLog(@"%s", __PRETTY_FUNCTION__);

2
के साथ __FUNCTION__और इसके काफी समकक्ष भी सी-कार्यों में उपलब्ध है।
जॉर्ज फ्रिट्ज़

NB __FUNCTION__में वर्ग का नाम भी शामिल है
Orange26

1
क्या NSLog (@ "% s", _func_ ) का उपयोग करने में कोई अंतर है ; या NSLog (@ "% s", _PRETTY_FUNCTION_ ) ???
रवि

83

tl; डॉ

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

विवरण

Apple के पास एक तकनीकी प्रश्नोत्तर पृष्ठ है: QA1669 - मैं अपने लॉगिंग स्टेटमेंट में संदर्भ जानकारी कैसे जोड़ सकता हूं - जैसे वर्तमान विधि या लाइन नंबर?

लॉगिंग में सहायता करने के लिए:

  • C प्रीप्रोसेसर कुछ मैक्रो प्रदान करता है ।
  • उद्देश्य-सी अभिव्यक्ति (तरीके) प्रदान करता है ।
    • वर्तमान विधि के चयनकर्ता के लिए निहित तर्क पारित करें :_cmd

जैसा कि अन्य उत्तर दिए गए हैं, केवल वर्तमान विधि का नाम प्राप्त करने के लिए, कॉल करें:

NSStringFromSelector(_cmd)

वर्तमान विधि नाम और वर्तमान लाइन संख्या प्राप्त करने के लिए , इन दो मैक्रोज़ का उपयोग करें __func__और __LINE__जैसा कि यहां देखा गया है:

NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);

एक और उदाहरण ... कोड के स्निपेट मैं Xcode के कोड स्निपेट लाइब्रेरी में रखता हूं:

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

… और ERROR के बजाय TRACE…

NSLog( @"TRACE %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

... और मूल्य को पार करने वाले एक नरम-कोडित विवरण का उपयोग करके लंबे समय तक [rows count]...

NSLog( @"TRACE %@ METHOD %s:%d.", [NSString stringWithFormat:@"'Table of Contents.txt' file's count of Linefeed-delimited rows: %u.", [rows count]] , __func__, __LINE__ );

लॉगिंग के लिए प्रीप्रोसेसर मैक्रोज़

मैक्रो के दोनों किनारों पर अंडरस्कोर वर्णों की एक जोड़ी के उपयोग पर ध्यान दें ।

| मैक्रो | प्रारूप | विवरण
  __func__% s वर्तमान फ़ंक्शन हस्ताक्षर
  __LINE__% d वर्तमान लाइन संख्या
  __FILE__% s स्रोत फ़ाइल का पूर्ण पथ
  __PRETTY_FUNCTION__% s जैसे __func__, लेकिन इसमें वर्बोज़ शामिल है
                                    C ++ कोड में जानकारी टाइप करें। 

लॉगिंग के लिए अभिव्यक्ति

| अभिव्यक्ति | प्रारूप | विवरण
  NSStringFromSelector (_cmd)% @ वर्तमान चयनकर्ता का नाम
  NSStringFromClass ([स्व वर्ग])% @ वर्तमान वस्तु का वर्ग नाम
  [[NSString% @ स्रोत कोड फ़ाइल नाम
    stringWithUTF8String: __ FILE__]   
    lastPathComponent] 
  [NSThread callStackSymbols]% @ NSArray of स्टैक ट्रेस

लॉगिंग फ्रेमवर्क

कुछ लॉगिंग फ्रेमवर्क वर्तमान पद्धति या लाइन नंबर प्राप्त करने में मदद कर सकते हैं। मुझे यकीन नहीं है, जैसा कि मैंने जावा ( SLF4J + LogBack ) में एक महान लॉगिंग फ्रेमवर्क का उपयोग किया है, लेकिन कोको नहीं।

विभिन्न कोको लॉगिंग फ्रेमवर्क के लिंक के लिए यह प्रश्न देखें ।

चयनकर्ता का नाम

यदि आपके पास एक चयनकर्ता चर (एक SEL ) है, तो आप इस कोडेक ब्लॉग पोस्ट द्वारा वर्णित तरीके से इसका विधि नाम ("संदेश") दो तरीकों से प्रिंट कर सकते हैं :

  • NSStringFromSelector में उद्देश्य-सी कॉल का उपयोग करना :
    NSLog(@"%@", NSStringFromSelector(selector) );
  • सीधे सी का उपयोग करना:
    NSLog(@"%s", selector );

यह जानकारी 2013-07-19 के रूप में लिंक किए गए Apple doc पृष्ठ से ली गई है। वह पृष्ठ आखिरी बार 2011-10-04 में अपडेट किया गया था।


1
C के लिए, sel_getName(SEL)SEL के बाद से उपयोग एक अपारदर्शी प्रकार है और हमेशा नहीं हो सकता हैchar *
Ethan Reesor

8
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift

4
जो कोई भी भविष्य में इस उत्तर के लिए आता है: यह स्वीकृत उत्तर के बराबर है, लेकिन स्वीकृत उत्तर अलग था, जब यह पोस्ट किया गया था (स्वीकृत उत्तर को 2014 में संपादित किया गया था)। मैं वोट डाउन करने वाला था, लेकिन एक छोटी जांच के बाद वोट देने के बजाय :)
FreeNickname

0

यह वास्तव में बस के रूप में सरल है:

printf(_cmd);

किसी कारण से आईओएस _cmd को शाब्दिक चार के रूप में पारित करने की अनुमति देता है, यहां तक ​​कि एक संकलित चेतावनी भी नहीं। कौन जाने


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.