This article is based on iPad in Practice, to be published on Summer 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]
Debug Logging
Introduction
In Cocoa, the default logging function NSLog can be useful for adding some log information to your application but, unfortunately, it runs in all build configurations. On the Mac, that may not be a big deal but, on the iPhone, you can and will notice a performance impact when NSLog calls are being made in a processor-intensive situation. You should use NSLog sparingly; in fact, I prefer not to use it at all and use a debug logging approach like the one outlined in this technique for all my log output.
Problem
Using NSLog for debug output seems like a perfectly good solution until you realize that NSLOg will run in all build configurations, even in release and distribution builds where you get very little benefit from it. On the iPhone, NSLog calls can impact the performance of your code by adding unneeded overhead, so it’s important to have a way to provide logging that will only run in debug or test build configurations.
Solution
In order to support logging for debug build configurations only, we’re going to implement a simple varargs macro that you can place in the *_Prefix.pch precompiled header file of your projects (see listing 1).
Listing 1 AppName_Prefix.pch
// Debug logging function #ifdef DEBUG # define DLog(...) NSLog(__VA_ARGS__) #else # define DLog(...) while(0) #endif
The DLog function is very simple. It uses an ifdef to determine if it should be enabled or not. If the debug flag is set, then it defines DLog to run NSLog so you’ll get the same logging behavior you’re used to with NSLog. If the debug flag is not set, it simply runs an empty false while loop, which will return immediately.
Now that the DLog function has been defined, you can enable it for your debug configurations by editing the Project Configuration.
Select Project > Edit Project Settings, choose the Debug configuration in the Configuration dropdown. Now search for Other C Flags (found in the GCC 4.2 section of the build settings). Then, add a new entry, -DDEBUG=1, to enable the DEBUG flag.
Figure 1 Setting Debug flag
Discussion
By implementing a debug logging function as a macro and using the OTHER_C_FLAGS compiler setting, we can easily manage the build configurations in which our logging will actually be included. The DLog function is a very simple macro that makes any calls to DLog return immediately if the DEBUG flag is not enabled for the current build configuration. This approach to logging means you will not have to worry about your logging impacting the performance of your final product.
Summary
We discussed the technique for adding Debug logging to give you a nice alternative to using NSLog.