How to disable NSLog all over the app? - ios

I want to disable NSLog() across all instances in an app. I found some code that does that:
#ifndef DEBUG
#define NSLog //
#endif
But adding this code to each file isn't good idea. How can I make it easier?

Xcode has a precompiled header file ({project-name}-Prefix.pch in the Supporting Files group by default) that is a great place to put code that will be used across every file in the project. For going a step further and improving the log message itself, see Is it true that one should not use NSLog() on production code?.

Add the following lines to your constants file:
#define DEBUGGING NO //or YES
#define NSLog if(DEBUGGING)NSLog
The two following sentences give the same results
#define NSLog
and
#define NSLog //
because all text that begin with // are deleted in a precompiling phase ("//" included)

What I do is put this in the precompiled header file (YourAppName.pch):
#define MyLog if(0); else NSLog
Then I change all NSLog to MyLog everywhere else in the app. It works as if it were NSLog. But when you want to disable NSLog, go back to the .pch file and change the 0 to 1 and presto, all logging stops.

This will also take care of the warnings that arise when using
#define NSLog //
The code:
#ifndef DEBUG
#define NSLog(...)
#endif

Just add the following lines when you do'"t need NSLOG to your constants file
#define NSLog //
and comment it when you need it.

Related

Xcode compiler errors when using ##__VA_ARGS__

Here is my customized NSLog.
#define NSLog(fmt, ...) printf("🌳🌳🌳%s,%d\n %s\n\n", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:fmt, ##__VA_ARGS__].UTF8String)
This log is work good on another project, but it occurred 4 error when compiler time in current project. If using __VA_ARGS__, like #define NSLog(...) NSLog(__VA_ARGS__), it's going to compile successful. I think that maybe caused in Building Setting.
It's anyone has any idea to help me to solve this.
Check that the header file declaring this imports Foundation. Check that you don't have NSLog defined somewhere else as well and finally, really not a good idea to redefine NSLog. You're probably better off adopting a logging framework or defining your own like this:
#define MELog(fmt, ...) NSLog("🌳🌳🌳%s,%d\n %s\ ....

#ifdef DEBUG versus #if DEBUG

It is unclear to me when using compiler directives which of the below two code snippets is correct/preferred and why. It seems that most developers and Open Source projects I've seen use the first but I have seen the second used frequently as well.
#ifdef DEBUG
[self doSomethingOnlyWhenDebugging];
#endif
VERSUS
#if DEBUG
[self doSomethingOnlyWhenDebugging];
#endif
Which of the above code snippets is preferable for running code only while debugging and why? My guess is that the first will run if DEBUG is defined as TRUE or FALSE where the second will run only if DEBUG is defined and set to TRUE. Is that correct?
You are correct. #if DEBUG will not evaluate if DEBUG is defined as 0.
As for when to use each, you can stick to using #ifdef for anything where you only need to add code if the preprocessor definition is present, such as adding debug logging. If you need to inspect the value and go down different compilation paths, then I would use a 0 or 1. A good example of that is TARGET_IPHONE_SIMULATOR, which is always defined for an iOS project, but only 1 if you’re compiling for the simulator.
As I know, the finest choice is:
#ifndef DEBUG
NSLog(#"-1");
#elif DEBUG == 0
NSLog(#"0");
#else
NSLog(#"%d", DEBUG);
#endif
then, you will know #ifndef DEBUG is preferred above all others.
There is a simpler choice:
#if DEBUG == 0 // DEBUG is not defined or defined to be 0
// do sth
#else
// do sth
#endif
However, if -Wundef compiler flag is on, there might be a warning with #if DEBUG == 0.
You need to look at the code where DEBUG gets defined or not defined, and write your code accordingly. With DEBUG, you will find that it is either not defined, or defined with a value of 1. So either #if DEBUG or #ifdef DEBUG will work.
For #define's that are under your control, I recommend that you always define them, either with a value of 0 or 1. You can then use #if to check for the value, but you can also use them directly in an ordinary if statement or in an expression, which may make your code more readable. And since it is always defined, you can use "Jump To Definition" in Xcode to go to the place where it is defined and check how and why it is set. If instead you either #define or not #define the value, and it is not defined, then Xcode will have no idea where in your source code it is not defined. It also gives you a chance to look for misspelled uses. If "Jump to Definition" doesn't work, then you know you have spelled it wrong.
BTW Within an #if directive, any macro that is not defined is replaced by 0. So #if DEBUG will work if DEBUG is not defined, or if DEBUG is defined as 0, and it will not compile if DEBUG is defined as nothing - which will tell you what is wrong so you can fix it. From that point of view, using #if is better unless it doesn't compile.

'Undeclared Identifier' error with defined constants

My defined constants are giving me 'undeclared identifier' issues. I have them in a Constants.h file that I am including in my .pch file. I thought it might be something with my .pch file, however, if I delete it from there and try #import it in one of the classes where I need one of the constants, then I still get an 'undeclared identifier' error.
If I take each #define line and put them at the top of the .m class file directly, they work. So my syntax is correct.
So it's something with the .h file itself, but I have no idea what.
//
// Constants.h
// Sliding Drawer
#define kOffscreenX 320 // X coord when Sliding Drawer is offscreen
#define kVisibleX 40 // X coord when Sliding Drawer is visible
// WordlistButton
#define kNumScores 3
// Fonts
#define kMessageFontSize 14
#define kScoreFontSize 10
It's impossible to see the error only from this piece of code. Preprocessor tends to create very messy things, especially when there are circular imports involved.
You can try to delete the current compiled version of the header, note it's not in the derived data folder, it's in XCode's cache (see Project -> Build Setttings -> Precompiled Headers Cache Path).
However, if you have tried to import Constants.h directly and it didn't work, the problem may be somewhere else.
Are you sure there is only 1 file called Constants.h? Note you should use a prefix for your files (e.g. SAConstants.h if Smooth Almonds is your name) to avoid collision with Apple's headers or headers of the libraries you are using.
If you import the header directly, go to the .m file and tap on Product -> Generate Output -> Preprocessed File and find Constants.h import in it. Is it your header?
By the way, there is a nice article about avoiding this kind of things in precompiled headers http://qualitycoding.org/precompiled-headers/
I found this thread due to an other error upper case parameter in my define statement. I solved it for my issue with lower casing:
#define MSB(BTvalue) ((uint8_t) (BTvalue >> 8)) //threw this error
changing BTvalue to just value with lowercase parameter made me happy
#define MSB(value) ((uint8_t) (value >> 8))

Sequence of execution when loading xib?

I have been programming on iOS for almost six months now, using xibs left and right, but i am still unaware how loading process works...
What i mean, i have view controller and push button to open new modal view controller. From that point onwards how are things done. Is init method first called, then xib created, outlets connected and then nib loaded?
Is there any good article or book that explains this in details?
this maybe not answer your question the way like you want,
but i recommend you to find it out yourself.
How? see the text above.
use XLog() in case of NSLog()
paste the code above in your prefix.pch file
put in every method you want an XLog() statement and see, which methods are called firstly.
XLog() is a better way of NSLog(). In console you can see the Line numbers and the methodnames where the log is called. this should help you out to understand the way of loading nibs.
#define DEBUG 1
//#define RELEASE 1
#ifdef DEBUG
// Debug definitions
#define DEBUG_MODE
#define XLog(fmt, ...) NSLog(#"%s line:%d " fmt, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#ifndef RELEASE
#error DEBUG or RELEASE need to be #defined
#endif
// Release definitions
#define RELEASE_MODE
#define XLog(...)
#endif

#define NSLog(p1, ...); does not work in Xcode 4.3.1

I use
#define NSLog(p1, ...);
to put logging off in my code. Then I use
//#define NSLog(p1, ...);
to put logging on in my code
This doesn't seem to have any effect now that I use Xcode 4.3.1.
Am i doing something wrong? Or is there an alternative?
Use #define kMyString #"This is my string text!" and then use NSLog(#"String: %#",kMyString);
I found the solution. The difference with the previous version of Xcode is that
#define NSLog(p1, ...);
doesn't work anymore when i put this code in the .m file. It only works from the .h file

Resources