Is there any particular flag which can be set to not display NSLog output in either debug or release?
Thanks.
One option might be to use a macro as a replacement for NSLog (if its easy for you to change things at this point). I like the prefix header file these guys use:
http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/
Basically their logging function is:
#ifdef DEBUG
#define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
#define DLog(...) do { } while (0)
#endif
So if you are not in a DEBUG build, the logging macro becomes a no-op.
Generally, people write their own macro -- something like DebugLog -- for logs to be "compiled out":
#undef DebugLog
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS] )
#else
#define DebugLog( s, ... )
#endif
Adding this b/c none of the answers seem to address warnings you may have (depending on project settings) with some of these approaches.
This is the only way I could find to suppress NSLog without getting any warnings. Otherwise I get a ton with the settings we use (warn on unused variables).
#undef NSLog
#define NSLog(fmt, ...) if (0) { printf("%s", [[NSString stringWithFormat:fmt, ##__VA_ARGS__] UTF8String]); }
Then all you need to do is put that in whatever pch file you use for your release builds or wherever you want to suppress the logs.
Credit to @Hot Licks for the example of how to make the variable "used".
Default flag with a new Xcode project is DEBUG
for Debug and none for Release. So you will hide NSLog
in Release this way:
#ifndef DEBUG
# define NSLog(...)
# define NSLogv(...)
#endif
Or if you want pretty custom logs as well (not using #ifdef
here because no simple #elifdef
):
#if DEBUG
# define NSLog(format, ...) NSLog((@"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__)
# define NSLogv(format, ...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [[NSString alloc] initWithFormat:format arguments:__VA_ARGS__])
#elif ADHOC
// default logs
#else// Release
# define NSLog(...)
# define NSLogv(...)
#endif
And if you want to override those macros and still log something sometimes, you can use:
(NSLog)(@"This log is always visible!");
Now, how to hide those as well? It would require you to #define NSLog NoLog
and define NoLog as an extern function with an empty implementation like void NoLog(NSString *format, ...) {}
. But it could be cleaner to avoid using (NSLog)
altogether and instead use a function with a LogLevel enum:
typedef NS_ENUM(NSUInteger, LogLevel) {
LogLevelRelease,
LogLevelAdHoc,
LogLevelDeveloper,
};
void CustomLog(LogLevel level, NSString *format, ...) {
#if !DEBUG
if (LogLevel == LogLevelDeveloper)
return;
#if !ADHOC
if (LogLevel == LogLevelAdHoc)
return;
#endif
#endif
va_list ap;
va_start (ap, format);
NSLogv(format, ap);
va_end (ap);
}
The drawback of this CustomLog is that arguments get always evaluated, even in Release. So an optimal solution is multiple macros:
#define NSLog(format, ...) NSLog((@"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__)
#if DEBUG
# define DebugLog(...) NSLog(__VA_ARGS__)
# define AdHocLog(...) NSLog(__VA_ARGS__)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#elif ADHOC
# define DebugLog(...)
# define AdHocLog(...) NSLog(__VA_ARGS__)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#else// Release
# define NSLogv(...)
# define DebugLog(...)
# define AdHocLog(...)
# define ReleaseLog(...) NSLog(__VA_ARGS__)
#endif
check for Debug mode using this macro
#ifdef DEBUG
//NSLog(@"XYZ");
#endif
Above NSLog will not get printed in Release mode
You can define a macro in the precompiled header (.pch) to disable NSLog:
#ifdef RELEASE
# define NSLog(...)
#endif
This disables NSLog in release builds.