Do you have any unique or special uses of NSLog you use for debugging?
NSLog is the objective C way of using printf (although printf works too), so its always useful to be able to see the contents of variables. The fact that it also prints out a time stamp before the output can be an easy way to see exactly how long the program is spending doing each specific task.
I like to use this format for debugging.
NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
Of course, you'll want to wrap this in your own method or function for ease of use. I use the preprocessor and also only enable it for my own use and special builds I send out to beta testers. This is copied from my answer to this question, by the way.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
This makes DebugLog
act just like NSLog
, but displays the filename and line-number where it was called:
2009-05-23 17:23:40.920 myproject[92523:10b] <AppCon.m:(8)> My debug message...
I use some macros with NSLog to quickly debug the contents of cocoa's NSPoint
, NSSize
, and NSRect
structs:
#define LogPoint(POINT) CMLog(@"%s: (%0.0f, %0.0f)",\
#POINT, POINT.x, POINT.y)
#define LogSize(SIZE) CMLog(@"%s: %0.0f x %0.0f",\
#SIZE, SIZE.width, SIZE.height)
#define LogRect(RECT) CMLog(@"%s: (%0.0f, %0.0f) %0.0f x %0.0f",\
#RECT, RECT.origin.x, RECT.origin.y,\
RECT.size.width, RECT.size.height)
These can be used as follows:
LogPoint(somePoint);
LogSize(someSize);
LogRect(someRect);
And they produce the following output:
somePoint: (100, 200)
someSize: 12 x 440
someRect: (120, 240) 326 x 74
NSLog(@"%s", __PRETTY_FUNCTION__);
prints the current method signature or function name.
This is not an NSLog feature, however it’s very handy for use with NSLog: you can use %@ placeholder for objects, and their descriptions will be displayed:
NSLog (@"The object is %@", someKindOfObjectWhichYouWantToDisplay);
This way you can quikly see what object you get returned, for example. This works by sending “description” selector an object, which can be, of course, implemented in your own objects.
Here's one that lets you indent some portions of your debugging logs to make things more readable:
// MyDebugStuff.h:
void MyLog_Indent();
void MyLog_Outdent();
void MyLog(NSString * format, ...);
// MyDebugStuff.m:
int logIndentLevel = 0;
void MyLog_Indent() { logIndentLevel++; }
void MyLog_Outdent() { if (logIndentLevel > 0) { logIndentLevel--; } }
void MyLog(NSString * format, ...)
{
va_list args;
va_start(args, format);
NSString * indentString = [[NSString stringWithString:@""]
stringByPaddingToLength:(2*LogIndentLevel)
withString:@" "
startingAtIndex:0];
NSLogv([NSString stringWithFormat:@"%@%@", indentString, format], args);
va_end(args);
}
This can be used like so:
MyLog(@"Hello, world");
MyLog_Indent();
MyLog(@"Step 1");
MyLog(@"Step 2");
MyLog_Indent();
MyLog(@"Step 2a");
MyLog(@"Step 2b");
MyLog_Outdent();
MyLog(@"Step 3");
MyLog_Outdent();
MyLog(@"Goodbye, cruel world!");
And will produce:
Hello, world Step 1 Step 2 Step 2a Step 2b Step 3 Goodbye, cruel world!