Reputation: 1007
What's the best way to define the following ternary operator?
[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ? x : y
I considered using the macro
#define phonePad(x, y) ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ? x : y)
But this article mentions that it may not be the best idea. Is there a way to do the equivalent using a C function or is this the best way of implementing it?
Upvotes: 1
Views: 141
Reputation: 13947
Neither.
BOOL isiPhone = ([[UIDevice currentDevice] userInterfaceIdiom]
== UIUserInterfaceIdiomPhone);
foo = isiPhone ? x : y;
bar = isiPhone ? xprime : yprime;
...
If you turn that into a macro, you'll get a bunch of unnecessary calls into the Objective-C runtime. So just cache the result. Plus, it'll probably be a lot easier to read if you just write plain C code instead of using a macro.
Upvotes: 1
Reputation: 130193
I wouldn't use a macro for this. By using a macro, you require for the device to check the user interface idiom ever time this is used, and set x or y accordingly. Consider making a new method that returns based on the interface idiom. This can be static, because it's impossible for this value to ever change at runtime.
- (id)determineXOrY {
static id obj = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
obj = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ? x : y
});
return obj;
}
Upvotes: 4
Reputation: 318794
If you do use the macro you must add some parentheses:
#define phonePad(x, y) ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ? (x) : (y))
Without the parentheses you will have serious issues if x
or y
are more than simple values.
One downside to the macro is that you really need to be sure that both x
and y
evaluate to the same non-ambiguous data type.
Upvotes: 0