NSLog
is a good debugging tool some of the time. Coming from AS3 I am quite used to trace statements, and even fancy AIR solutions for runtime tracing and variable lookups and tweaking. I realize that NSLog
isn’t the best way to debug applications, but it certainly is handy. However those log statements can clutter code and slow down a release application. They can slow your debug build down quite a lot as well.
I’ve seen solutions that wrap NSLog with #ifdef
statements and what a colossal pain in the ass that can turn out to be. No thanks, unless I inherit that code. It might be nice to simply have a checkbox someplace in Xcode that will either include logging for debug builds or will not include it. Release would never have them included. Potentially. Wouldn’t that be better than using conditionals or NSLog replacements?
I planned on linking up a long list of present solutions – but you’re probably either very aware of them already or know the limitations in using them. They make things easier, yes. But in my opinion not a true solution. I’m looking to Apple Xcode developers to make this much more elegant.
I tried to log this as a feature with Apple (radar) but for me login produced a non-descript error. A humorous note in regards to the error page were two HTML comments in the resulting page.
<!-- Radarweb -8160537 Starts Commented by shyam 12-Oct-2010 RadarWeb: ErrorDetail doesnt work a lot of time, may be none of the time -->
<!-- Radarweb -7661372 End:Added and Commented by Dinesh 10-Feb-2011 RadarWeb: Bug Reporter's hyperlinks do not do anything -->
They are right – I get no error detail and the hyperlink for “Home” does absolutely nothing. Personally I’d love to see the bug reporter overhauled and given a nice coat of paint. Sure it’s just a bug reporting tool, but it looks like it was made ten or more years ago and is stuck there. It’s using webobjects – perhaps that’s part of the reason?
Too many active tickets in the wild to turn the thing off? They could maybe make another subdomain and get that going and when it’s prepared perform a redirect to it? Transfer all the stuff over? I don’t know the impact of the work such a thing would entail – but it would be most welcome for the developer community.
Update:
#define USE_DEBUG_LOG 1 #if DEBUG && USE_DEBUG_LOG #define DebugLog(s, ...) NSLog(s, ##__VA_ARGS__) #else #define DebugLog(s, ...) do { } while (0) #endif
Above you’ll see _prefix code that I’ve added. I use DebugLog instead of NSLog now. I define the USE_DEBUG_LOG so I can turn off logging even in a debug build (it’s a nice bit of flexibility) – since that’s already defined as 1 for default debug builds.
I might add in the class name and line number of the logging as well – not sure I’d find that useful or not. I’ve seen others use it.
Another Update:
I decided it would be useful to add the Class identification as well as the line number the log originated. So now the additional prefix code looks like this:
#define USE_DEBUG_LOG 1 #if DEBUG && USE_DEBUG_LOG //#define DebugLog(s, ...) NSLog(s, ##__VA_ARGS__) #define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) #else #define DebugLog(s, ...) do { } while (0) #endif
And yet another take on it, massaging the output for the DebugLog:
#define USE_DEBUG_LOG 1 #if DEBUG && USE_DEBUG_LOG #define DebugLog( s, ... ) NSLog( @"[%p %@] %@:(line %d): %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], NSStringFromSelector(_cmd), __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] ) #else #define DebugLog(s, ...) do { } while (0) #endif
With the above you can get DebugLog statements that look like this:
2013-03-21 13:10:14.741 ProjectName[27564:907] [0x1cd5ac20 ViewController.m] viewDidLoad:(line 25): Hello there