Why does adding and subtracting two #define'd macros not work on iPhone / Objective-c
In my iPhone app, I have this in my .h file
#define ORIENTATION_IS_PORTRAIT UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])
#define FULLSCREEN_开发者_高级运维MODE ORIENTATION_IS_PORTRAIT?460:300
#define AD_HEIGHT ORIENTATION_IS_PORTRAIT?50:32
#define FULLSCREEN_MODE_WITH_AD FULLSCREEN_MODE - AD_HEIGHT //doesn't work
To sum it up, I have a macro to detect the orientation. I have another for the height of my UIWebView
when it is in full screen mode (activated by a button press). I need to keep the ad at the bottom. However, to get the height of the UIWebView
minus the ad height will only return the AD_HEIGHT
.
For addition, (FULLSCREEN_MODE + AD_HEIGHT
) returns the FULLSCREEN_MODE
only.
Also, when using constants, where exactly do I put them. I searched and could only find answers like "in the .m file", but where??
What you want is to have it like this:
#define FULLSCREEN_MODE (ORIENTATION_IS_PORTRAIT?460:300)
#define AD_HEIGHT (ORIENTATION_IS_PORTRAIT?50:32)
#define FULLSCREEN_MODE_WITH_AD (FULLSCREEN_MODE - AD_HEIGHT)
For more complex expressions, I'd suggest you wrap that in do { ... } while(0)
instead of just grouping them together.
What's happening here is it's being parsed as:
UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? 460 : 300 - UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? 50 : 32
which is not the math you want.
Surround every macro with ()
- it's a good habit and will save you some unexpected behavior.
example:
#define FULLSCREEN_MODE (ORIENTATION_IS_PORTRAIT?460:300)
The preprocessor does a direct replacement of one piece of text for another. If you have order of operations issues, the parentheses will save you.
Alternately, avoid the preprocessor and it's confusion altogether, and use inline functions.
inline BOOL orientationIsPortait() {
return UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]);
}
inline int fullscreenMode() {
return orientationIsPortait() ? 460 : 300;
}
... etc
These would go outside of your @implementation block.
For that matter, I'd bet you don't run these function but once in a great while, so thinking about optimizations like macros or inlining is highly premature, and probably never important.
Avoid macros. Define functions. You can declare them inline
.
精彩评论