Logging Current Method or Function

104 views
Skip to first unread message

Jonathan Hohle

unread,
Dec 12, 2008, 12:26:35 PM12/12/08
to xcodep...@googlegroups.com
Last night there was a discussion about various methods of logging the current method, here's a quick summary of some of the options.

As Jiva mentioned, you can use GCC's built in __PRETTY_FUNCTION__ macro. This expands to a C string which includes the method type (instance or class), class name, and method name. Using a log line like this:

NSLog(@"%s", __PRETTY_FUNCTION__);


Will print a log line similar to:

2008-12-12 09:22:49.552 Healthcheck[79016:20b] -[HealthcheckAppDelegate applicationDidFinishLaunching:]


And as Brad said, there are a lot more of these macros, and some implicit variable definitions, too (__func__, for example):

    NSLog(@"%s", __PRETTY_FUNCTION__); // gcc Extension

    NSLog(@"%s", __FUNCTION__); // gcc Extension

    NSLog(@"%s", __FILE__); // C++ Macro (but works in gcc)

    NSLog(@"%d", __LINE__); // C++ Macro (but works in gcc)

    NSLog(@"%s", __func__); // Specified in C99


Note that __LINE__ expands to an int, not a C string.

Another method I use is the hidden _cmd parameter passed to an Objective-C method. (You can get a function pointer to any Objective-C method which the signature void* (void*)(id self, SEL _cmd, ...)). _cmd is the method's selector and there are several method for dealing with selectors directly. To print a line with just the current method name:

NSLog(NSStringFromSelector(_cmd));


This prints a similar line to the one above, but with less information:

2008-12-12 10:06:00.299 Healthcheck[79365:20b] applicationDidFinishLaunching:


I've found _cmd to be useful when writing classes with delegates. Generally the delegate has the same (or similar) signature to the class that received the original message. That can be used to your advantage:

- (void) performAction: (id) sender

{

    if ([delegate respondsToSelector: _cmd]) {

        [delegate performSelector: _cmd withObject: sender];

    }

}


With IBActions or UIResponder delegates, this can be common, and a macro or two can reduce the repetition:

#define forwardAction(d, s) \

    if ([d respondsToSelector: _cmd]) { [d performSelector: _cmd withObject: s]; }


#define forwardTouch(d, t, e) \

    if ([d respondsToSelector: _cmd]) { [d performSelector: _cmd withObject: t withObject: e]; }


- (void) performAction: (id) sender { forwardAction(delegate, sender); }


- (void) performAnotherAction: (id) sender { forwardAction(delegate, sender); }


But now this has gotten off the topic of logging and on to something altogether different.

-- 
Jon
<><
Reply all
Reply to author
Forward
0 new messages