Ian1971
Ian1971

Reputation: 3706

Boolean logic failure

I am having a strange problem with boolean logic. I must be doing something daft, but I can't figure it out. In the below code firstMeasure.isInvisibleArea is true and measureBuffer1 is nil. Even though test1 is evaluating to NO for some reason it is still dropping into my if statement. It works ok if I use the commented out line. Any idea why this happens?

BOOL firstVisible = firstMeasure.isInVisibleArea;
BOOL notFirstVisible = !(firstMeasure.isInVisibleArea);
BOOL measureBufferNil = measureBuffer1 == nil;

BOOL test1 = measureBuffer1 == nil && !firstMeasure.isInVisibleArea;
BOOL test2 = measureBufferNil && !firstVisible;

if (measureBuffer1 == nil && !firstMeasure.isInVisibleArea)
//if (measureBufferNil && !firstVisible)    
{
    //do some action
}

Update 1:

I isolated the problem to !firstMeasure.isInVisibleArea as I've entirely taken on the measureBuffer bit. Inside isInVisible area is a small calculation (it doesn't modify anything though), but the calculation is using self.view.frame. I am going take this out of the equation as well and see what happens. My hunch is that self.view.frame is changing between the two calls to isInVisibleArea.


Update 2: This is indeed the problem. I have added the answer in more detail below

Upvotes: 0

Views: 502

Answers (4)

Ian1971
Ian1971

Reputation: 3706

My hunch was correct, it is related to the view frame changing between calls to firstMeasure.isInVisible area.

This whole routine is called in response to the view moving. I think I need to grab the value of firstMeasure.isInVisibleArea at the start of the method and use that value throughout.

Phew. Boolean logic isn't broken. All is right with the world.

Thanks for all your input

Upvotes: 0

Alex
Alex

Reputation: 26859

While you certainly can parenthesize, you should also know that nil objects evaluate to boolean NO and non-nil objects evaluate to boolean YES. So you could just as easily write this:

BOOL firstVisible = firstMeasure.isInVisibleArea;
BOOL notFirstVisible = !(firstMeasure.isInVisibleArea);
BOOL measureBufferNil = measureBuffer1;

BOOL test1 = !measureBuffer1 && !firstMeasure.isInVisibleArea;
BOOL test2 = measureBufferNil && !firstVisible;

if (measureBuffer1 && !firstMeasure.isInVisibleArea) {
    //do some action
}

You would end up with the same results. I agree with GoatRider, though. It's always far better to parenthesize your conditional expressions to clarify what you really want to happen than it is to rely on the language's operator precedence to do it for you.

Upvotes: 4

GoatRider
GoatRider

Reputation: 1213

When in doubt, you should fully parenthesize. Without looking up the precedence rules, what I think what is happening is that = is getting higher precedence than == or &&. So try:

BOOL test1 = ((measureBuffer1 == nil) && !firstMeasure.isInVisibleArea);

Upvotes: 5

Kevin Crowell
Kevin Crowell

Reputation: 10140

If test1 is evaluating to NO as you say, then drop test1 into the if statement:

if(test1){
    //see if this executes?
}

See what that does.

Upvotes: 2

Related Questions