NSLog the method name with Objective-C in iPhone
Solution 1
print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
Swift 3 and above
print(#function)
Solution 2
To technically answer your question, you want:
NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);
Or you could also do:
NSLog(@"%s", __PRETTY_FUNCTION__);
Solution 3
tl;dr
NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
Details
Apple has a Technical Q&A page: QA1669 - How can I add context information - such as the current method or line number - to my logging statements?
To assist with logging:
- The C preprocessor provides a few macros.
- Objective-C provides expressions (methods).
- Pass the implicit argument for the current method's selector:
_cmd
- Pass the implicit argument for the current method's selector:
As other answers indicated, to merely get the current method's name, call:
NSStringFromSelector(_cmd)
To get the current method name and current line number, use these two macros __func__
and __LINE__
as seen here:
NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);
Another example… Snippets of code I keep in Xcode's Code Snippet Library:
NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
…and TRACE instead of ERROR…
NSLog( @"TRACE %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
…and a longer one using a soft-coded description passing a value ([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__ );
Preprocessor macros for logging
Note the use of a pair of underscore characters around both sides of the macro.
| Macro | Format | Description __func__ %s Current function signature __LINE__ %d Current line number __FILE__ %s Full path to source file __PRETTY_FUNCTION__ %s Like __func__, but includes verbose type information in C++ code.
Expressions for logging
| Expression | Format | Description NSStringFromSelector(_cmd) %@ Name of the current selector NSStringFromClass([self class]) %@ Current object's class name [[NSString %@ Source code file name stringWithUTF8String:__FILE__] lastPathComponent] [NSThread callStackSymbols] %@ NSArray of stack trace
Logging Frameworks
Some logging frameworks may help with getting current method or line number as well. I'm not sure, as I've used a great logging framework in Java (SLF4J + LogBack) but not Cocoa.
See this question for links to various Cocoa logging frameworks.
Name of Selector
If you have a Selector variable (a SEL), you can print its method name ("message") in either of two ways as described by this Codec blog post:
- Using Objective-C call to NSStringFromSelector:
NSLog(@"%@", NSStringFromSelector(selector) );
- Using straight C:
NSLog(@"%s", selector );
This information drawn from the linked Apple doc page as of 2013-07-19. That page had been last updated 2011-10-04.
Solution 4
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift
Related videos on Youtube
vodkhang
I am interested in quite a range of things from hard core like database system, intelligent to mobile and Human Usability @vodkhang My blog
Updated on December 10, 2020Comments
-
vodkhang over 3 years
Currently, we are defining ourselves an extended log mechanism to print out the class name and the source line number of the log.
#define NCLog(s, ...) NSLog(@"<%@:%d> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \ __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__])
For example, when I call NCLog(@"Hello world"); The output will be:
<ApplicationDelegate:10>Hello world
Now I also want to log out the method name like:
<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world
So, this would make our debugging become easier when we can know which method is getting called. I know that we also have Xcode debugger but sometimes, I also want to do debugging by logging out.
-
Jacob Relkin about 14 yearsIn my last
iPhone
project, I actually did this manually. Would love to see the answer to this. -
erkanyildiz about 10 yearsPossible duplicate: stackoverflow.com/questions/969130/…
-
-
Georg Fritzsche about 14 yearsWith
__FUNCTION__
and its pretty equivalent also being available in C-functions. -
Nick Forge about 14 yearsYou really should use
NSLog(@"%@", NSStringFromSelector(_cmd))
, if you're going to use_cmd
, since AFAIK Apple declares_cmd
as typeSEL
, not a C-string. Just because it happens to be implemented as a C-string (as of the current versions of Mac OS X and the iPhone OS) doesn't mean you should use it in that way, since Apple could change it in an OS update. -
drawnonward about 14 yearsYes, NSStringFromSelector is the more correct answer. I never use _cmd as c string for anything but debug code.
-
Nicolas Miari about 12 yearsWow, the compiler complaints about pointer incompatibility, but it works... So _cmd (type: SEL) really is a char* !?
-
Jack Lawrence over 11 yearsMethod calls like
[self doSomething:arg1 somethingElse:arg2]
get converted into the C function callobjc_msgSend(self, "doSomething:somethingElse:, arg1, arg2);
. The second parameter ofobjc_msgSend()
takes achar*
. Remember that because the Objective-C runtime is dynamic, it's actually using a lookup table to figure out which method on which class to call so a char* is convenient since methods are represented as strings in the lookup table. -
Ethan Reesor over 10 yearsFor C, use
sel_getName(SEL)
since SEL is an opaque type and might not always be achar *
-
OrangeDog over 10 yearsN.B.
__FUNCTION__
also includes the class name -
FreeNickname about 9 yearsFor anyone who comes across this answer in the future: it is equivalent to the accepted answer, but the accepted answer was different, when this one was posted (the accepted answer was edited in 2014). I was about to down vote, but after a small investigation up voted instead :)
-
Jake Lin about 8 yearsFor Swift 2.2 should use
print("\(#function)")
-
Ravi about 6 yearsis there any difference using NSLog(@"%s",_func_); OR NSLog(@"%s", _PRETTY_FUNCTION_) ???