11 Mar 2009, 22:44

A better NSLog

Share

When debugging, I often found that NSLog is really boring, here is an attempt to make it nicer:

`

NSLog(@"mycar: %@",myCar);
NSLog(@" I'M HERE ");

`

NSLog doesn’t tell you where the call was made (which file or which method), so you end with a lot of:

2009-03-11 22:30:53.789 ObjCTest[1565:10b] mycar: Porsche

2009-03-11 22:30:53.791 ObjCTest[1565:10b] I’M HERE

A better NSLog could tell us:

2009-03-11 22:32:25.823 ObjCTest[1581:10b] Car.m:32 -[Car init] I’M HERE AND I KNOW WHERE I AM

Now we have the sourcefile, the linenumber and the method of the call !!

Another repeating action when debugging is just to look for the value of something (call the description method of an object)

`

NSLog(myCar);
NSLog(@"%@",myCar);

`

That will produce:

2009-03-11 22:38:22.707 ObjCTest[1625:10b] Porsche

Not really sexy, no filename, no name for that value … a better answer could be:

2009-03-11 22:38:22.708 ObjCTest[1625:10b] Car.m:35 -[Car init] [myCar description] = Porsche

To enable this “better” NSLog, in the Source folder of your Xcode you will find a file named YOURAPPNAME_Prefix.pch add the following code

`

#include <libgen.h>
#define ALog(format, ...) NSLog([NSString stringWithFormat:@"%s:%d %s %@",basename(__FILE__),__LINE__,__FUNCTION__,format], ##__VA_ARGS__)
#define ALogv(var) NSLog([NSString stringWithFormat:@"%s:%d %s [" # var " description] = %@",basename(__FILE__),__LINE__,__FUNCTION__, var] )

`

A much better solution is to associated it with a DEBUG define, and put ‘-DDEBUG=1’ it in “Other C Flags” in Xcode Debug configuration, explained here, it will remove all calls to ALog when buit for release.

`

#ifdef DEBUG
#include <libgen.h>
#define ALog(format, ...) NSLog([NSString stringWithFormat:@"%s:%d %s %@",basename(__FILE__),__LINE__,__FUNCTION__,format], ##__VA_ARGS__)
#define ALogv(var) NSLog([NSString stringWithFormat:@"%s:%d %s [" # var " description] = %@",basename(__FILE__),__LINE__,__FUNCTION__, var] )
#else
#define ALog(...) /* */
#define ALogv(var) /* */
#endif

`

Then call ALog rather than NSLog and ALogv for the variable name and his value:

`

  ALog(@"mycar: %@", myCar);
  ALogv(myCar);

2009-03-11 22:38:22.706 ObjCTest[1625:10b] Car.m:33 -[Car init] mycar: Porsche
2009-03-11 22:38:22.708 ObjCTest[1625:10b] Car.m:35 -[Car init] [myCar description] = Porsche

`

Feel free to change the name of this functions.

Bye Bye NSLog.

EDIT: here is the update version I’m using

2009-07-31 12:22:46.070 WheelOfFate[30351:20b] [WheelBrowserViewController.m:26 initWithStyle:] myWheelStorage=

What is this strange method ? In fact this is just [TheFileWhereTheMethodeWasCalled:TheLineNumberTheMethodWasCalled TheMethod], it sounds strange but it takes less space on debug console, warning sometimes where you define multiple class in same file it could fool you.

Why DLog instead of ALog ? Just run xcode and type dl you will see that there is no completion for DL letters …

What is this new ALogm method (Log Method) ? Sometimes you just need to display “the application has gone here” without any others informations.

`

#ifdef DEBUG
#include <libgen.h>
#define DLogm() NSLog([NSString stringWithFormat:@"[%s:%d %@]",basename(__FILE__),__LINE__,NSStringFromSelector(_cmd)])
#define DLog(format, ...) NSLog([NSString stringWithFormat:@"[%s:%d %@] %@",basename(__FILE__),__LINE__,NSStringFromSelector(_cmd),format], ##__VA_ARGS__)
#define DLogv(var) NSLog([NSString stringWithFormat:@"[%s:%d %@] "# var "=%@",basename(__FILE__),__LINE__,NSStringFromSelector(_cmd), var] )
#else
#define DLog(...) /* */
#define DLogv(var) /* */
#define DLogm() /* */
#endif

`