For clarity sake - am I understanding this?

Discussion in 'iOS Programming' started by Tander, Jun 28, 2013.

  1. Tander macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #1
    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:
     
  2. MeFromHere macrumors 6502

    Joined:
    Oct 11, 2012
    #2
    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.
     
  3. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #3
    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.
     
  4. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #4
    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.

     

Share This Page