Getting Started
Tutorials
Core
Style
UI
Three20 Timeline

Debugging with three20

Source: github

TTDebug.h contains a set of useful debug tools, including priority-based logging and debug-only assertions. These macros deprecate the original Three20 TTLOG macros and Xcode NSLog methods that were difficult to disable (and tended to cause an unending stream of log messages). The goal of the new logging framework is to make it easy to see the logs you care about.

Table of Contents

How to turn on logging

All you need to do is define a DEBUG preprocessor definition in the GCC_PREPROCESSOR_DEFINITIONS option in your debug target settings. You shouldn't define this for your release build.

Add the preprocessor definitions

If you want to enable logging for Three20, you will need to add a preprocessor definition to the Three20 lib like so: TTMAXLOGLEVEL=TTLOGLEVEL_INFO. You'll need to actually open the Three20 project and change its settings for this to work.

If you want to enable logging for your own project, you will need to add a preprocessor definition to your project like so: TTMAXLOGLEVEL=TTLOGLEVEL_INFO.

Logging

The logging system introduces a new set of macros.

TTDERROR(text, ...)    // Log level 1
TTDWARNING(text, ...)  // Log level 3
TTDINFO(text, ...)     // Log level 5
TTDPRINT(text, ...)

Each of the above logging macros eventually routes the logs through TTDPRINT, but the messages will only be displayed if the message's priority level is below the TTMAXLOGLEVEL threshold. If you don't explicitly set TTMAXLOGLEVEL, the default is set to TTLOGLEVEL_WARNING, meaning only warning and error logs will be displayed.

The standard output of TTDPRINT looks something like this:

TTDPRINT(@"Is this thing on?");
2009-11-20 13:46:49.613 AppName /path/to/file/Filename.m(86): Is this thing on?

Conditional Logging

New since Dec 5, 2009

Conditional logging allows you to use logging methods that only produce output when a certain condition is met. A quick example:

TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @"Request parameters: %@", request.parameters)

This will only produce the log if the flag TTDFLAG_URLREQUEST is set to a non-zero value. You can see a set of basic Three20 conditional log flags in TTDebugFlags.h.

Debug-only assertions

It can often be useful to validate the parameters passed into a method. The method may return preemptively if the parameters are invalid or missing. This is a way to fail somewhat gracefully. When you're actively developing code, however, it would be ideal if the method could shout out to you "hey, listen!", letting you know that the method is being abused.

This is where TTDASSERT comes in. It works like a regular assertion - in that if you pass a zero-value to it, it lets you know - but it has the nice benefit of not crashing your app. Instead, it jumps straight into the debugger at the line that caused the issue. It's also gracefully compiled away in release builds, so your shipping product will never know they existed.

Consider this example:

-(void)safeAddSubview:(UIView*)view {
  TTDASSERT(nil != view);
  if (nil == view) {
    return;
  }
  [self addSubview:view];
}

Let's say we then call [myView safeAddSubview:nil]. In debug builds of the app, calling this will now toss us into the debugger at the culprit line and output a quick log explaining the problem.

2009-11-20 14:10:53.096 AppName...
  /path/to/file/Filename.m(86): TTDASSERT failed: nil != view

Some things to note about debug assertions.

Debug assertions will only fire in the simulator. On debug device builds the assertion will fail, output a log message, and then carry forward.

If you're in the simulator and debug assertions aren't starting up the debugger, it's likely because you're not starting the app with gdb attached. To ensure that you always attach gdb to the app when you start it, use the hot-key Cmd+Y instead of Cmd+Enter.

Last modified: Friday the 23rd of April 2010 10:46:09 PM