views:

177

answers:

6

EDITED FOR TYPO -

How can I check one thing AND THEN another, if the first is true?

For example, say I have a shopping basket object, and I only want to do something if the basket has been created AND it isn't empty.

I've tried:

if ((basket) && ([basket numberOfItems] >0))...

But the second condition is evaluated even if the first fails, resulting in a crash (presumably because i'm calling numberOfItems on an object that doesn't exist).

I can nest them, but this seems a bit ugly, and more to the point is problematic. Say I want to do one thing if the basket exists AND isn't empty, but another if either isn't true. That doesn't really work well in nested if statements.

A: 

if((basket) && (basket numberOfItems > 0)).....

or

if(basket != null)

if the basket object is not created or not assigned value then in this condition.... first it will check if there is basket object assigned value....only if it is true then only it will check another condition.....and if both is true then only it will in to that if part.....

Nitz
You shouldn't compare an Obj-C object reference to `NULL` (there is no such thing as `null` in Obj-C/C BTW). To test if an Obj-C object reference is "null" (non-existant), you compare it to `nil`.
Nick Forge
+11  A: 

If Objective-C is a strict superset of C (which, in my understanding, it is), then boolean evaluation short circuits with the && and || operators. This means that since you're using &&, as soon as a condition fails, the remaining conditions are not even evaluated.

Given your code, that means that if the object is null, then the message is never dispatched.

Adam Robinson
+1  A: 

Your code has the > within the method, was that a copy paste fail? If not that is your problem.

Garrett
Should be a comment.
Paul R
+5  A: 

Your understanding is not correct; the && operator does "short circuit" the way that you want. Your problem is somewhere in your own code.

If the crash is really on this line, then:

  1. Your basket pointer is not nil. If it were, the call to numberOfItems would do nothing and return NO, which is the default behavior for messaging nil (not crashing).
  2. basket might have been an object once, that's already been dealloced by this point, and is now blowing up on sending it a message.
  3. basket might be some other (non-nil) garbage pointer. In this case or the one above, you'd probably see EXC_BAD_ACCESS in the debugger.
  4. basket might not support a numberOfItems method. This usually is made quite explicit in the debugger.

If the crash is possibly not on this actual line, then something else could be up, too.

(updated per OP update & helpful comments)

quixoto
agree.. [basket numberOfItems >0] makes little sense. should be [basket numberOfItems] >0
Ben
To be clear: basket is either a deallocated object or a garbage pointer. Neither of those is equal to nil.
Chuck
+1  A: 

Sounds to me like basket is a dangling pointer. Check to make sure you're properly retaining it and setting it to nil if you release it without setting it to a valid object immediately afterward.

Wevah
A: 

to expand on what others have said: && does short circuit, but & does not. However, as others have said, in objective C, you can send methods to nil without error, so short circuiting isn't your problem. (I just mentioned & for completeness).

I think the most likely problem is that you are at some point creating a basket, and then releasing it, but never setting it back to nil... so, basket isn't nil, but it's also not a valid object...

it might help if you told us what the actual error message was when it crashed... My theory would give an error message that says something about sending a message to a released or garbage collected objet, or something like that...

Brian Postow