Reputation: 7484
i have a two deep if statement and i'm wondering if i can condense to a single if stmt:
if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]])
{
if (((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
{
//code
}
}
i'm not sure if i can make it into:
if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]] && ((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
since the second if condition is dependent on the first (if it is not a UILabel and doesn't have a .tag value) can bad things happen?
Upvotes: 0
Views: 101
Reputation: 38728
As everyone has identified this is possible but readability is the main issue. Although the use of whitespace in suggestions is good
if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]]
&& ((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
{
//code
}
I personally would still find I have to do a double take to understand what those statements are doing so sometimes it may be worth taking the readability a bit further
UILabel *label = [myScrollView.subviews objectAtIndex:k]
BOOL isLabel = [label isKindOfClass:[UILabel class]];
BOOL hasSuitableTag = label.tag >= i;
if (isLabel && hasSuitableTag) {
//code
}
OR to keep the short circuit (Thanks @CocoaFu)
UILabel *label = [myScrollView.subviews objectAtIndex:k]
BOOL isLabel = [label isKindOfClass:[UILabel class]];
if (isLabel && label.tag >= i) {
//code
}
The result reads a bit more like english (if you expand it in your had) is a label and has a suitable tag
. It may slightly longer but when your reading it back in a weeks time you'll appreciate the added typing.
Programs must be written for people to read, and only incidentally for machines to execute.
Abelson & Sussman, Structure and Interpretation of Computer Programs
Upvotes: 2
Reputation: 69342
The &&
operator stops evaluating when it reaches a false clause. So long as the evaluations don't cause any side-effects there shouldn't be any problems.
However, newlines and white-space are your friend for legibility:
if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]]
&& ((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
{
//code
}
Upvotes: 3
Reputation: 16714
You can do it the second way. Basically, in an AND statement the compiler will check the first statement and if it is false it won't check the second statement... so the second/inner statement only gets evaluated when the first statement is true.
Upvotes: 1
Reputation: 34902
You can combine them like that, yes. If the first statement fails then it fails the entire if
statement and doesn't execute the 2nd part.
For ease of reading I would probably write it like this though:
if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]] &&
((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
{
// code
}
Upvotes: 6
Reputation: 41801
That's fine. C (and by extension, Objective-C) && expressions are "short-circuiting". If the first clause evaluates to false, the second clause isn't evaluated.
Upvotes: 4