58

I want to enable NSLog when I am in debug and disable it otherwise. A very simple thing is:

#ifdef DEBUG
NSLog(@"My log");
#endif

But all this #ifdef and #endif is borring... :( So I try other thing: (.pch is good place to put it)

#ifdef DEBUG
#   define NSLog(text) NSLog(text);
#else 
#   define NSLog(text) 
#endif

This work very fine (isn't recursive). But the problem is that NSLog have infinite arguments.

void NSLog(NSString *format, ...)

How I solve this to work in preprocessor mode?

-- Edit --

This code make your NSLog better:

#ifdef DEBUG
    #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
    #define NSLog(...)
#endif
5
  • +1 for Nice Question. A complete reusable component on this topic at mobile.tutsplus.com/tutorials/iphone/… Commented Aug 18, 2013 at 4:42
  • I follow the guide in the link. But I got the following compile error: Undefined symbols for architecture x86_64: ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Please help @MahbuburRAaman Commented Dec 2, 2013 at 3:19
  • @Gon, Error Undefined symbols for architecture x86_64: ld: symbol(s) not found for architecture x86_64 appears for several reason. For example, for missing library or other cases, have a look at the following SO resource stackoverflow.com/questions/18408531/…, stackoverflow.com/questions/11996227/… , stackoverflow.com/questions/6231368/…. Commented Dec 2, 2013 at 13:54
  • 1
    @MahbuburRAaman Thanks for replying. I've found the reason is I'm calling this custom NSLog method from a objective c++ file. Commented Dec 2, 2013 at 14:17
  • Please, where have I to place this code? Commented Mar 22, 2017 at 14:50

5 Answers 5

110

This should do the trick:

 #ifdef DEBUG
 #   define NSLog(...) NSLog(__VA_ARGS__)
 #else 
 #   define NSLog(...) (void)0
 #endif
Sign up to request clarification or add additional context in comments.

4 Comments

It's fine but replace # define NSLog(...) NSLog(VA_ARGS); with # define NSLog(...) NSLog(VA_ARGS) (remove last ;)
@JustSid: How do I set or reset the DEBUG flag?
This doesn't play nice with the ternary operator.
@StianHøiland While it's questionable wether ternary operator around void is a good idea to begin with, I've updated the code so that it does support it.
19

This is a bit shorter and also disables NSLog when using a device. If you're writing a game, NSLogs sent often can reduce your FPS from 60 to 20.

#if !defined(DEBUG) || !(TARGET_IPHONE_SIMULATOR)
    #define NSLog(...)
#endif

Comments

8

All the above answers are correct. I can suggest you to do it in a following way also. Suppose i have a if statement with no brackets

if(x==5)
NSLog("x is 5");

What will happen if it will replace NSLog with no statement. So we can simply replace it with an empty loop.

#ifdef DEBUG
#define NSLog(...) NSLog(__VA_ARGS__)
#else
#define NSLog(...) do {} while (0)
#endif

This statement will run an empty loop once. This will safely remove your NSLog from all of your live code.

4 Comments

Good point, and that’s also a good place to repeat that using if statements without brackets is probably a bad idea in the first place.
the code will be preprocessed to if (x==5) ; which is fine.
This doesn't play nice with the ternary operator.
if you have a common constants file that is included in .pch then place in that, otherwise you can place it at top of class before @implementation
1
#ifndef Debug
    #define Debug 1
#endif

#if Debug
#   define DebugLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DebugLog(...)
#endif

Set Debug to 1 for enabling the log and 0 for disabling it.

1 Comment

You can create Constant Header file and add the code to it and for accessing you just need to the import the Header file and use the DebugLog function to log the variables you desire to....
1

Here is a nice trick... add to any .m

#define EXTRANSLog if([[NSUserDefaults standardUserDefaults] boolForKey:@"SomeFancyKey"] == YES) NSLog 

Replace any

NSLog(@"????");

with

EXTRANSLog(@"????");

In this example, I created a NSUser key and set the BOOL to YES,, use some form of switch etc to change the key to NO or remove altogether if you don't want to view the EXTRANSLog's via console debugger.

I use this when troubleshooting and don't want all the excessive logs to appear. Only when SomeFancyKey == YES.

This is the same as

#define NSLog if(1) NSLog

where 1 is YES show NSLog, and 0 is NO.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.