Padin215
Padin215

Reputation: 7484

combing IF statements

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

Answers (5)

Paul.s
Paul.s

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

Ben S
Ben S

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

Michael Frederick
Michael Frederick

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

mattjgalloway
mattjgalloway

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

Catfish_Man
Catfish_Man

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

Related Questions