Archive for July, 2009
NSLog() sucks
July 18, 2009 8:15 amIn a previous installment I explained why printf() sucks, and how I fixed it. Today I am going to focus on NSLog(), which sucks even worse.
Why NSLog() sucks
Here’s a typical NSLog() call:
NSLog(@"hello: %d", 6);
Note that it doesn’t require a newline character at the end of the format string. So we’ve made a little progress over printf(). It’s not until you see the output that we get to what I think is wrong with it:
2009-07-18 08:48:29.067 nslog_sucks[44201:10b] hello: 6
Sigh. Just as with printf(), NSLog() is optimized for a corner case I hardly ever need. The assumption is that I would always want to know when this action took place down to a thousandth of a second, and that I’d want to see the name of the program doing the output, the program’s PID, and so on. The output I’m interested in is drowned out by unimportant noise.
Replacing NSLog() with something better
This is how NSLog() is defined, in NSObjCRuntime.h:
FOUNDATION_EXPORT void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
At first glance, it appears that this would give you the same sort of warning that you get with printf() if the format string doesn’t match the arguments supplied. Sadly, I’ve never been able to coax GCC into supplying warnings in that case. But I added the same __attribute__ decoration to my NSLog() replacement, in case this is just a bug in current versions of GCC that will be fixed at some point in the future.
Finally, here’s the source code for nlog(), my NSLog() replacement that doesn’t fill the screen with unnecessary details. The header file, nslog_sucks.h:
// nslog_sucks.h -- an NSLog() alternative // by allen brunson july 18 2009 #ifndef NSLOG_SUCKS_H #define NSLOG_SUCKS_H #include <Foundation/Foundation.h> // nlog(), a better NSLog() void nlog(NSString* nfmt, ...) __attribute__((format(__NSString__, 1, 2))); #endif // NSLOG_SUCKS_H
And the implementation file, nslog_sucks.m:
// nslog_sucks.m -- an NSLog() alternative // by allen brunson july 18 2009 #include <stdio.h> #include <stdlib.h> #include <Foundation/Foundation.h> #include "nslog_sucks.h" void nlog(NSString* nfmt, ...) { va_list args = NULL; NSString* nstr = nil; va_start(args, nfmt); nstr = [[NSString alloc] initWithFormat:nfmt arguments:args]; va_end(args); puts([nstr UTF8String]); [nstr release]; nstr = nil; } int main(int argc, const char** argv) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; nlog(@"hello from nlog: %s %d", "text", 2); [pool release]; pool = nil; return 0; }
Categories: cocoa, iphone, mac, objective-c, programming
Comments Off

