Please consider subscribing to Mobile Developer Tips RSS feed or following us on Twitter
|
|
|
Although NSlog is convenient for outputting messages to the console, I tire of the date/time and object information that it prints.
As an alternative, one can craft a macro that uses CFShow, which outputs Core Foundation objects to stderr. CFShow uses callbacks to objects to display their descriptions, which allows one to use “%@” like you would when calling NSLog.
I often include the following debug definition as part of my projects:
#define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
A few short examples follow showing the difference in output between NSLog and the debug macro shown above.
1
2
3
4
5
6
7
8
9
10
11
12
| struct point
{
int x;
int y;
};
typedef struct point POINT;
POINT topLeft;
topLeft.x = 15, topLeft.y = 20;
NSLog(@"x: %d y: %d", topLeft.x, topLeft.y);
debug(@"x: %d y: %d", topLeft.x, topLeft.y); |
The output will now look as follows:

Here’s another example, this time passing in an object:
1
2
3
4
5
6
7
8
9
10
| NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
NSString *dateString = [dateFormat stringFromDate:today];
[dateFormat release];
...
NSLog(@"Date: %@", dateString);
debug(@"Date: %@", dateString); |
And the corresponding output:

Ahhh, much better.
Related posts:
- Date Formatter Examples – Take 1: NSDateFormatter
- Date Formatter Examples – Take 2: Format Strings
- C Structures
Comments
6 Responses to “Yet Another Debug Output (NSLog Replacement)”
Leave Comment
Why not just use printf? You could do the following:
NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
NSString *dateString = [dateFormat stringFromDate:today];
[dateFormat release];
…
NSLog(@”Date: %@”, dateString);
printf(“Date: %s”, [dateString cString]);
[Reply]
I agree, printf will work fine as you’ve shown, however, with printf you need to call the appropriate method to convert each object to its string representation or call the description method on the object. NSLog and/or CFShow will handle this process for you.
[Reply]
Thanks for the post.
I added #define NSLog(…) CFShow([NSString stringWithFormat:__VA_ARGS__])
to MyApp_Prefix.pch and it works beautifully.
[Reply]
It doesn’t work with ARC, I get the following:
error: Automatic Reference Counting Issue: Implicit conversion of an Objective-C pointer to ‘CFTypeRef’ (aka ‘const void *’) is disallowed with ARC
Any thoughts?
Regards,
Tim
[Reply]
@Tim: A bridge cast seems to do the trick:
#define debug(format, …) CFShow((__bridge void *)[NSString stringWithFormat:format, ## __VA_ARGS__]);
[Reply]
Stumbled on this one somewhere…
#define PrintName NSLog(@”?”, __FUNCTION__);
[Reply]