Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

PriapusZA

macrumors 6502a
Original poster
Oct 21, 2011
677
1
England
Hi all,

So I have been trying to wrap my head around the bit of code below - I *think* I understand what it's doing. The question is am I?

Here is the code:

Code:
    //Lazy instaintation

- (NSMutableArray *)cards
{
    if (!_cards) _cards = [[NSMutableArray alloc]init];
    return _cards; 
}

As I understand this:

If the cards array doesn't exist - then create one. This way we only ever create the array when we need it - memory optimisation - right?

Next is this bit of code (Using the not operator again )

Code:
- (IBAction)newGameButton:(UIButton *)sender
{
    sender.selected =!sender.isSelected;
}

As I understand this:

If the UIButton is not selected - then tapping the button will make it UIControlState selected (UIControlStateSelected)
if the button is selected this will reverse the above line of code and change it's state to: (UIControlStateNormal) - right?

As far as I understand this operator - it does the opposite. So in the example of our cards araay:

If it does exist - do nothing. (Method won't run) if it doesn't (not) exist then it will create an array of cards..

My problem is just when I am reading these for of lines of code that include the not operator - sometimes it isn't 100% clear what it's doing. Is there an *easy* way to rethink of this operator for better understanding when writing / reading code?



P.S: Sorry for all the n00b questions of late - my first few months of being an actual iOS developer is providing a steep learning curve. Then again I am trying to get up to speed ASAP so maybe that's why I am stumbling a little?


Thanks again all! :cool:
 
Expressions in C (and related languages like C++ and Objective C) are complicated. The language has more operators than some other common languages, many of them have terse, somewhat bizarre syntax, and of few them are just plain weird. The "logical not" (!) operator is just one of many on the learning curve.

Figuring out the behavior of complex C expressions is just hard; nearly everyone struggles with it at some point. I think the most effective way to deal with the problem is always the same: learn to break down a complicated expression into small parts that you can understand.

For simple expressions, you'll soon develop intuition that makes the thinking process faster. But nearly everyone finds a level of complexity where their intuition fails, and they have to go back to breaking the expression into smaller parts.

You have two example of expressions using the "not" operator. The operator does the same thing in both, but the result of the expression is used in two different ways. In the first case, the result is used as the condition in an "if" statement; in the second case, it is the right-hand side of an assignment statement. So you have three separate concepts to understand here:
  1. expression using "not" operator
  2. if statement
  3. assignment statement
Do you have a good understanding of those three things, and where your examples use each of them? You need to learn to see the boundaries between different kinds of code in a program. Declaration, statement, expression, etc.

"not" is a "unary" operator, which means it is applied to ONE value (which is whatever is to the right of the operator in the expression). C also has "binary" operators (which are applied to two values) and one "ternary" operator (which is applied to 3 values). But your examples don't have any binary or ternary operators.

The "not" operator always does the same thing: when applied to a value of 0, the result is 1; when applied to any other value, the result is 0.

Now look at your first example. You have an "if" condition that's the result of the "not" operator, so the condition is either 0 or 1. You already know how an "if" statement works. The reason the code is written this way is due to a convention in C: a pointer with a value of 0 doesn't point to anything.

So... if _cards is 0, it doesn't point to anything. The expression !_cards has the value 1, so the statement following the "if" executes. The statement makes a (non-zero) pointer value and assigns it as the new value of _cards. If the function runs again, _cards is non-zero, so !cards is 0, and the "if" doesn't execute the following statement.

Your description of the second example,
sender.selected = !sender.isSelected​
is right. If the variable is 0, the function changes it to 1; if it is non-zero, the function changes it to 0. (I'm assuming without looking it up that UIControlStateSelected and UIControlStateNormal are just symbolic names that mean 0 and 1.)

I hope this long-winded reply helps. Sometimes it's hard to know just what part of the example is causing confusion, so I apologize if my explanation is too obvious and I missed the real question.
 
UIControlStates are actually rather complicated, but isSelected returns a Boolean and setSelected: (which is called in the background when you have .selected =) expects a Boolean.

Use isSelected, not .state, to determine if a button is selected, as controls can and often do have more than just two states.
 
You have a very detailed answer from another poster.

A very simple thing to be aware of:


Code:
if (!someValue)

is the same as writing

Code:
if (someValue == nil)

nil and 0 (zero) are the same thing.

So in your first example,

Code:
if (!_cards)

Could be rewritten as

Code:
if (cards == nil)

conversely, the code

Code:
if (cards)

means the same thing as

Code:
if (cards != nil)

In init mehods, you will often see this:

Code:
-(id) init;
{
  self = [super init];
  if (self) //means the same as "if (self != nil)"
  {
     //more init code here, only called if init succeeds.
  }

  return self;
}

or

Code:
-(id) init;
{
  self = [super init];
  if (!self)  //Means the same as "if (self == nil)"
    return nil; //init failed, return nil

  //more init code here
  return self;
}


Both of those init methods have the same effect. They call the superclass version of init, and return nil if it fails. If and only if super init returns a valid object, they go on to do other initialization.

They both use the funky
Code:
if (self)
and
Code:
if (!self)
syntax, which makes them a little hard for newbies to understand.

Hi all,

So I have been trying to wrap my head around the bit of code below - I *think* I understand what it's doing. The question is am I?

Here is the code:

Code:
    //Lazy instaintation

- (NSMutableArray *)cards
{
    if (!_cards) _cards = [[NSMutableArray alloc]init];
    return _cards; 
}

As I understand this:

If the cards array doesn't exist - then create one. This way we only ever create the array when we need it - memory optimisation - right?

Next is this bit of code (Using the not operator again )

Code:
- (IBAction)newGameButton:(UIButton *)sender
{
    sender.selected =!sender.isSelected;
}

As I understand this:

If the UIButton is not selected - then tapping the button will make it UIControlState selected (UIControlStateSelected)
if the button is selected this will reverse the above line of code and change it's state to: (UIControlStateNormal) - right?

As far as I understand this operator - it does the opposite. So in the example of our cards araay:

If it does exist - do nothing. (Method won't run) if it doesn't (not) exist then it will create an array of cards..

My problem is just when I am reading these for of lines of code that include the not operator - sometimes it isn't 100% clear what it's doing. Is there an *easy* way to rethink of this operator for better understanding when writing / reading code?



P.S: Sorry for all the n00b questions of late - my first few months of being an actual iOS developer is providing a steep learning curve. Then again I am trying to get up to speed ASAP so maybe that's why I am stumbling a little?


Thanks again all! :cool:
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.