14

I'm trying to debug an iPhone app I'm working on, and the idea of adding fifty NSLog statements to the various source files gives me the willies.

What I'd like to do is write a pair of statements, say

NSString *methodName = [self methodName];
NSLog(@"%@", methodName);

that I can just paste into each method I need to. Is there a way to do this? Is there some Objective-C construct for asking a method for its name? Or am I gonna have to do this the hard way?

Andy
  • 576
  • 1
  • 9
  • 23
  • This is an exact dup of http://stackoverflow.com/questions/2687785/any-way-to-ask-a-method-for-its-name/2687873#2687873 which has a more complete answer. – Ken May 05 '10 at 03:20
  • @Ken I know it's a bit 5 years late but I think your link is incorrect. It should point to http://stackoverflow.com/questions/969130/how-to-print-out-the-method-name-and-line-number-and-conditionally-disable-nslog?lq=1 – Can Poyrazoğlu Jun 13 '15 at 13:16

4 Answers4

23

Try NSLog(@"%s", __func__). This prints out a pretty description, like -[MyView drawRect:].

This also works with functions. It's a compiler feature.

Ken
  • 12,933
  • 4
  • 29
  • 32
  • 2
    `__func__` is a C99 language feature. Its cousins `__FUNCTION__` and `__PRETTY_FUNCTION__` are language extensions provided by GCC and possibly other compilers. All three are, I believe, extensions to the C++ language. – Jeremy W. Sherman Apr 23 '10 at 01:37
  • Exact dup of http://stackoverflow.com/questions/2687785/any-way-to-ask-a-method-for-its-name/2687873#2687873 – Ken May 05 '10 at 03:24
12

Use: NSLog("%@", NSStringFromSelector(_cmd));

_cmd is a special variable passed to every method just like self which is a reference to the selector that caused the method to be invoked (basically the method's name and signature).

Jason Coco
  • 77,985
  • 20
  • 184
  • 180
  • 1
    `NSLog( "%s" , _cmd );` A SEL is a C string. – drawnonward Apr 22 '10 at 03:41
  • 6
    @drawnonward yes it technically is, but it's still good to use the proper conversion functions. – Dave DeLong Apr 22 '10 at 04:07
  • 9
    @drawnonward: It is implemented as one, yes, but it defined as an opaque type. Apple is infamous for swapping things like that out from under you, so use it as documented regardless of how it's actually implemented. – Jason Coco Apr 22 '10 at 04:24
4

I use the following macros frequently:

#if DEBUG
#  define LOG(format, args ...) fprintf(stderr, format "\n", ## args)
#  ifdef __cplusplus
#    define ERR(format, args ...) fprintf(stderr, "[%s] (%s:%i): " format "\n", __PRETTY_FUNCTION__, __FILE__, __LINE__, ## args)
#  else
#    define ERR(format, args ...) fprintf(stderr, "[%s] (%s:%i): " format "\n", __func__, __FILE__, __LINE__, ## args)
#  endif
#else
#  define LOG(format, args ...)
#  define ERR(format, args ...)
#endif

If you always wanted the function name you could easily adapt them as required.

sbooth
  • 16,646
  • 2
  • 55
  • 81
2

This is what you want:

NSLog(@"%s", __PRETTY_FUNCTION__);

For more info on related logging stuff, read over the answers to this question: How to print out the method name and line number and conditionally disable NSLog?

Community
  • 1
  • 1
Nick Forge
  • 21,344
  • 7
  • 55
  • 78
  • 1
    `__func__` does the same thing (in all current Mac OS X compilers) and is guaranteed to exist by C99. Also, don't use `%@`, as both `__PRETTY_FUNCTION__` and `__func__` are C strings, not NSString objects. – Peter Hosey Apr 22 '10 at 05:14
  • Thanks for pointing out the %@ error (I've fixed the mistake now). Does `__func__` return the same thing as `__PRETTY_FUNCTION__` for Obj-C methods, C functions and C++ functions? I thought `__PRETTY_FUNCTION__` gave more info for C functions, like parameter names or something? – Nick Forge Apr 22 '10 at 05:30
  • Both identifiers have the same value in Objective-C methods (`-[MyClass selector]`) and C functions (`nameoffunc`) in both GCC 4.2.1 and Clang. I didn't test C++, because I don't know C++.. – Peter Hosey Apr 22 '10 at 19:50
  • 1
    For C++, `__func__` gives just the bare name of C++ member and static member functions. `__PRETTY_FUNCTION__` gives the entire shebang - everything that gets encoded into the mangled name. `void* A::B::C::DoIt(int, int)` yields `__func__ = __FUNCTION__ = DoIt` but `__PRETTY_FUNCTION__ = void* A::B::C::DoIt(int, int)`. – Jeremy W. Sherman Apr 23 '10 at 01:36