I have a method in objective-c that takes the parameter advertisement:(BOOL)advertisement. I'm wanting to send in a preprocessor "LITE_VERSION" as the parameter and if it exists I want it to return YES, and if it doesn't NO. Is there some safe way to accomplish this without having to write anymore code?
You'd be looking at something like:
#ifdef LITE_VERSION
return YES;
#else
return NO;
#endif
This would effectively harcode one of those two return statements at compile time based on LITE_VERSION.
Or you can make it even simpler if you can guarantee you'll set LITE_VERSION to a specific value of either YES or NO:
return LITE_VERSION;
Related
I am unable to get clear idea about the following method:
- (BOOL) isPad {
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
Actually for iPad applications this method is used but I don't understand that this method actually does, so if anyone could explain it in detail it would be very helpful for me.
Thanks in advance.
The method simply checks if the UI_USER_INTERFACE_IDIOM macro has been defined.
If it is available, it checks to see whether the macro is equal to UIUserInterfaceIdiomPad. If the comparison is true, it returns YES, otherwise if will return NO.
If the macro has not been defined, it means you are running iOS < 3.2 so it is definitely not an iPad.
For documentation, see http://developer.apple.com/library/ios/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/macro/UI_USER_INTERFACE_IDIOM
As the name suggests, tells you whether the current device that your app is running on is an iPad or not. Returns YES for iPad 1 & 2, and NO for iPhones and iPods.
The #ifdef is the pre-compiler checking to see if a variable UI_USER_INTERFACE_IDIOM is defined and then if it is defined as UIUserInterfaceIdiomPad. If it is defined as UIUserInterfaceIdiomPad that means it is being compiled for the iPad and returns YES, otherwise it returns NO.
I am new to objective-c and it seems to be very strange. I don't want to enable a method if a BOOL variable named "isFirstWordBeingAnimated" is equal to YES.
the variable isFirstWordBeingAnimated is equal to NO and for some reason it is treated as YES:
note that when I place the mouse on top of that variable meanwhile debugging xcode tells me that isFirstWordBeingAnimated is equal to NO. Why is it that the returns block gets executed !?
Moreover, I have set isFirstWordBeingAnimated=YES only on once of my code with a breackpoint:
I have not reached that breakpoint and xCode thinks it is equal to YES and I set that variable equal to NO when the view did loaded. Why is this?
Could it be because I have not defined the getters and setters? I defined isFirstWordBeingAnimated at the top of my .m file without creating the mutator (setter) and accessor (getter) methods...
EDIT
I have changed my code:
and I get the same problem:
First I would create a property in your header-file:
#property (nonatomic, assign, getter= isFirstWordBeingAnimated) BOOL firstWordBeingAnimated;
Also add to your main-file:
#synthesize firstWordBeingAnimated;
Next I don't like to use if(isEnabled)
return;
Better you put brackets around return;
if (isEnabled) {
return;
}
Try if (isEnbabled) instead of if (isEnabled==YES), I won't change anything, but I have no other ideas.
First of all, no need to use isFirstWordBeingAnimated == YES. Just stick the boolean in the parentheses and it will be evaluated for true or false. Secondly, you created the getter/setter fine but you're not actually using it. If you wanted to refer to the boolean or set it, use self.isFirstWordBeingAnimated.
On your problem, though, a boolean is always false unless you explicitly set it to true. In your case I believe the problem lies in the fact that your boolean is never created - thus making it false. If you wouldn't mind more code would help to understand exactly what you're doing.
I am trying to understand how to use blocks on iOS. I have read Apple's docs but, as usual, they are vague and incomplete and several essential bits of information are not mentioned. I have also googled around without success. This is what I am trying to do as an exercise to understand that.
I have created a block to read a string and compare the string to the previous read. If the strings are not the same, return YES, if they are the same, return NO.
This is how I did:
I declared this on .h
BOOL (^differentStrings)(void);
I declared this on .m, inside viewDidLoad in a viewController
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(#"%#", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
This is how I use: I have a thread that does this:
if (differentStrings)
NSLog (#"strings are different);
These are the problems I have:
the block always return YES (strings are different)
I am not comfortable declaring this inside videDidLoad. How should I declare this, so I can use it globally as a method? Should I put this like I would with a method?
I am calling a method "getString" inside the block. Is it OK?
I find strange to declare the block variables on .m. As I see, I should declare the block variables on .h and then just use them on .m. I have tried to do that, but received an error.
I have setup a debugging point on the first line of the block but it is not stopping there;
NSlog line inside the block do not prints anything. Isn't the block being called?
Can you guys help me with this?
You're misunderstanding how blocks work. (Okay, so that's kinda obvious.) In the same way that previousString is a variable pointing to an NSString, differentStrings is a variable pointing to a block. Not the result of running the block, but rather, the block itself. That is, after you do this:
__block NSString * previousString;
__block NSString * currentString;
differentStrings = ^(void){
currentString = [self getString];
NSLog(#"%#", currentString); // not printing anything on console
if (![currentString isEqualToString:previousString]) {
previousString = currentString;
return YES;
} else {
return NO;
}
};
differentStrings is a variable pointing to the block.Thus, when you do this:
if (differentStrings)
…you're simply checking whether differentStrings contains something other than 0 or NULL. Since it contains a block, it is not empty, so it evaluates to true.
Remember: differentStrings is a block variable, not a BOOL variable. It contains a block (a function, if you will), which when called will return a bool. Thus, in order to actually run the block, you need to call it. Like this:
differentStrings();
or, in your case:
if (differentStrings()) {
NSLog (#"strings are different");
}
Edit: As pointed out in the comments, since differentStrings is an instance variable, you need to copy it, just like you'd call retain on any other object assigned to an instance variable. (For technical reasons I won't go into now, you should always use copy with blocks instead of retain.) Likewise, you'll need to call release on it at some point later, perhaps in your dealloc method.
I don't believe you're actually executing the block. I think your code should be
if (differentStrings())
{
NSLog (#"strings are different);
}
Treat a block like a function. I think you were just checking to see whether the block had been defined, not executing it.
Also, if you don't need to access an NSString outside of the block, you could get rid of the __block qualifier and move the currentString declaration inside of the block.
If you need another resource on blocks, I cover them in the fall session of my advanced iOS development course on iTunes U. I describe block syntax in the Understanding Cocoa session, and their use in Grand Central Dispatch within the multithreading session. The course notes also have links to some sample applications that use blocks in different ways.
I also can't recommend highly enough that you watch the WWDC 2010 video sessions 206 - Introducing Blocks and Grand Central Dispatch on iPhone and 211 - Simplifying iPhone App Development with Grand Central Dispatch.
Is it possible at runtime to detect if the application that is running was compiled with debug or distribution.
In the Project Info, for a Debug configuration, add a Preprocessor Macro of "DEBUG" (in the GCC 4.2 - Preprocessing section).
In your code you can use #ifdef to see if DEBUG is defined if you want some code included or not for debug builds. Or you can even set a variable (I can't imagine why you would want this):
#ifdef DEBUG
BOOL isBuiltDebug = YES;
#else
BOOL isBuiltDebug = NO;
#endif
EDIT: Well, another way is to define a boolean value in a Preprocessor Macro, ie: "DEBUG_BUILD=1" for the Debug configuration, and "DEBUG_BUILD=0" for the Release configuration. Then you can use that value in your code:
if (DEBUG_BUILD) {
....
}
Just be careful not to use a macro name that could match a name that is already in your code or in any .h file that you might include either, because the preprocessor will replace it and it's a real pain to find those kinds of bugs.
Without having to think about defining a custom preprocessor macro, you can just write a custom method like this one :
+ (BOOL) isInDebugMode
{
#ifndef __OPTIMIZE__ // Debug Mode
return YES;
#else
return NO;
#endif
}
Or just write your code inline within those statements :
#ifndef __OPTIMIZE__ // Debug Mode
// Your debug mode code
#else
// Your release mode code
#endif
The __OPTIMIZE__ preprocessor setting in automatically set by the compiler regarding your project settings, so you don't have to worry about it.
I need a way to define a FLAGS_IF macro (or equivalent) such that
FLAGS_IF(expression)
<block_of_code>
FLAGS_ENDIF
when compiling in debug (e.g. with a specific compiler switch) compiles to
if (MyFunction(expression))
{
<block_of_code>
}
whereas in release does not result in any instruction, just as it was like this
#if 0
<block_of_code>
#endif
In my ignorance on the matter of C/C++ preprocessors I can't think of any naive way (since #define FLAGS_IF(x) #if 0 does not even compile) of doing this, can you help?
I need a solution that:
Does not get messed up if */ is present inside <block_of_code>
Is sure to generate 0 instructions in release even inside inline functions at any depth (I guess this excludes if (false){<block_of_code>} right?)
Is standard compliant if possible
Macros are pretty evil, but there's nothing more evil than obfuscating control statements and blocks with macros. There is no good reason to write code like this. Just make it:
#ifdef DEBUG
if (MyFunction(expression))
{
<block_of_code>
}
#endif
The following should do what you want:
#ifdef DEBUG
# define FLAGS_IF(x) if (MyFunction((x))) {
# define FLAGS_ENDIF }
#else
# define FLAGS_IF(x) if(0) {
# define FLAGS_ENDIF }
#endif
The if(0) should turn into no instructions, or at least it does so on most compilers.
Edit: Hasturkun commented that you don't really need the FLAGS_ENDIF, so you would instead write your code like this:
FLAGS_IF(expression) {
<block_of_code>
}
with the follow macros:
#ifdef DEBUG
# define FLAGS_IF(x) if (MyFunction((x)))
#else
# define FLAGS_IF(x) if(0)
#endif
I might do something like:
#ifdef DEBUG
const bool IS_RELEASE_MODE = false;
#else
const bool IS_RELEASE_MODE = true;
#endif
if (IS_RELEASE_MODE && MyFunction(expression))
{
...
}
This should get compiled out of release builds due to the fact that if (false && f()) is the same as if (false), which gets optimized out in most compilers.
That's if you're insistent on not using #ifdef on the inside of your code. Otherwise, I'd prefer the #ifdef DEBUG if (MyFunction(expression)) { ... } #endif that someone else posted.
Why can't you use the following?
#ifdef DEBUG
code for debug mode
#else
code for release mode
#endif
I generally try to avoid too much use of conditional compilation when possible.
For one, it's usually ugly and less readable.
But even more significantly, when projects use conditional compilation to turn debugging code on & off I have sometimes run into problems that the debugging code gets stale when it's disabled. Then when I want to actually use it debugging code, I turn it on and... Things. Don't. Build. Anymore.
The debug code may reference variables or functions that no longer exist, or things around the latent debugging code have otherwise changed enough that's it's just not syntactically valid anymore.
It can be really irritating.
So I've personally taken to avoiding conditional compilation to enable/disable debugging code in favor of using an enumeration or macro (that is still conditionally compiled) to use as the condition in an if statement. When compiled as an if (0) no runtime code gets generated - exactly as desired. But, the code is still compiled and syntax checked, so it's always at least syntactically correct.
#if NDEBUG // using the same standard macro that `assert()` uses
// use your own if NDEBUG doesn't make sense
enum {
DebugOn = 0
}
#else
enum {
DebugOn = 1
}
#endif
// ... elsewhere
if (DebugOn) {
// this always gets compiled, but if it's a release build
// the compiler will not emit anything...
}
As FryGuy mentioned, you can easily combine this with calling your MyFunction() if you like - in a release build, the function will not be called due to short-circuiting, which is the behavior you specified:
if (DebugOn && MyFunction( expression)) {
// this always gets compiled, but if it's a release build
// the compiler will not emit anything...
}
But personally, I'd probably use
if (DebugOn) {
if (MyFunction( expression)) {
// ...
}
}
Which I think helps call out a little more clearly (just a little) that this is a debug-only block.
This has the advantages of always being compiled and having no flow control hidden behind macros (which several other answers have mentioned as an evil).
How about something like this:
#ifdef DEBUG
#define FLAGS_IF(expr, block) { if (MyFunction(expr)) block }
#else
#define FLAGS_IF(expr, block)
#endif
You can use it like this:
FLAGS_IF(your_favourite_expression,
({
// some code
})
)