Accessing properties issue

Discussion in 'iOS Programming' started by nashyo, May 11, 2012.

  1. nashyo macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
    #1
    Code:
    CGRect bounds = label1.bounds;
        bounds.size = [label1.text sizeWithFont:label1.font];
        label1.bounds = bounds;
    why can't I write label1.bounds.size = [label1.text sizeWithFont:label1.font]; ?

    I get error expression is not not assignable ?
     
  2. CodeBreaker, May 11, 2012
    Last edited: May 11, 2012

    CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #2
    Size is not a property of UIView. Size is a member of CGRect (a C struct), which is a property of the UIView, i.e., it's frame. Actually, size is not at all an Objective C property ;) So you have to set it's frame.
     
  3. nashyo thread starter macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
  4. Ron C macrumors member

    Joined:
    Jul 18, 2008
    Location:
    Chicago-area
    #4
    I'm not exactly sure this is accurate for two reasons: a) he's not asking for view.size, he's asking for view.bounds.size which is exactly what you describe, and b) the problems isn't what you imply, rather it's that bounds.size is not a lvalue.

    It's really that latter issue that is the problem. You can't write bounds.size because it's not a lvalue (that is, a resolvable address that you can write on the left-hand side of an expression), it's the resolution of a method call which is typically a rvalue (that is, not writable). The reason you CAN write bounds is because it is a lvalue (or in particular there is a defined setBounds: method that is part of UIView).
     
  5. nashyo thread starter macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
  6. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #6
    Remember that the instance variables (ivars) in the object are accessed via get & set methods. So if you know that, you know that label1.bounds is referencing a get method, not a variable. Given that, you should now understand why you can't do what you ask. A method is not open to assignment.
     
  7. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #7
    I tried twice, but was not able to put it properly. :)

    This
     
  8. nashyo thread starter macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
    #8
    If what you say is true, then is the following not true?

    Code:
    Interface
    @property (monatomic, copy) NSString *apple;
    
    Implementation...
    @synthesize apple;
    
    self.apple = [[NSString alloc] initWithString:@"I have just assigned apple variable to this string"];
     
  9. xStep, May 13, 2012
    Last edited: May 13, 2012

    xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #9
    self.apple is shorthand for
    Code:
    -(void) setApple: (NSString *) anObject;
    Since you are actually referencing a function, and not the variable directly, you don't have access to the variable and it's possible inner structure.

    Read about the dot syntax in The Objective-C Programming Language. You'll have to click on 'Dot Syntax' in the left side menu. On the top right corner of that page is a button to download the PDF of the document.

    P.S. Your sentence, "I have just assigned apple variable to this string", is incorrect. It should have read, "I have just assigned this string to the apple variable".
     
  10. CodeBreaker, May 13, 2012
    Last edited: May 13, 2012

    CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #10
    Yes, you just assigned apple variable to this string. The thing is, self.apple calls setApple method on your instance. This is what setApple does:

    Code:
    - (void)setApple:(NSString *)newApple {
        [apple release]; //Release the old value
        apple = [newApple copy];  //Assign the new value
    }
    
    All this confusion is because the names of the instance variables and properties are the same. To get rid of this many developers prefix their synthesised instance variable names with an underscore. Kind of like this:

    Code:
    @synthesize apple = _apple;
    
    // So,
    // _apple = instance variable
    // [self apple] = getter
    // [self setApple] = setter
    
    
    Now, as xStep mentioned above, self.apple is a shorthand for [self setApple], only when you are assigning a value to it, i.e., when it is towards the left side of an equals sign. When you are accessing it's value, say like this:
    Code:
    NSLog(@"%@", self.apple);
    
    It will point to it's getter, which looks like this:
    Code:
    - (NSString *)apple {
        return _apple;
    }
    
    The dot notation was introduced to make Java/C++ programmers feel at home, since many don't like the square brackets Objective C uses.
     

Share This Page