i’m so full of ideas

Archive for July, 2009

NSLog() sucks

July 18, 2009 8:15 am

In 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; }