Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Chapter 3 Property statusLabel

I read in the Official Errata list that I should be referring to statusLabel as _statusLabel instead of just statusLabel. But I was looking at the sample code and I saw that you guys have just referred to it as statusLabel. After scanning the file for other references, I saw this line: @synthesize statusLabel; I copied the exact same line in my file and I could refer to statusLabel as it is without using underscore. So I went back to p.49 of the text on outlet and @property and I didn't see any information on @synthesize. I am pretty certain this will be explained moving forward but my curiosity can't wait for when it is introduced, so can you please explain what is this construct for? 

Thank you very much for your attention.

Comments

  • As far as I understand:


    1) You can synthesize a property explicitly in your code, just like you mentioned: @synthesize statusLabel


    Then you can refer to it in your code as "statusLabel":


    statusLabel = ...


    2) When synthesizing, you can even give a property a different name to refer to it

    @synthesize statusLabel = someDifferentName


    Then you can refer to it in your code as "someDifferentName":


    someDifferentName = ...


     it is recommended by Apple though that you use not just some random name like "someDifferentName" but a property name with preceding underscore:


    @synthesize statusLabel = _ statusLabel;


    3) You do not have to synthesize a property, because if you do not synthesize a property explicitly in your code, Xcode will do that for you behind the scene (you won't see it in your code). And when doing that, Xcode follows Apple's recommendation of course, so it will do it as  @synthesize statusLabel = _ statusLabel; (as I said, you won't see it in your code)


    So, if you do not synthesize a property, Xcode does it for you, and you can just refer to it with underscore.


    4) In all cases you can also refer to your property as self .<property name>, like that:


    self.statusLabel 


    Summary:


    - you can use @synthesize statusLabel, and then use statusLabel (is not recommended though)

    - you can just use _statusLabel 

    - you can just use self.statusLabel, and that is the most preferable way


  • Thank you very much for your answer with excellent examples. I have 2 follow up questions:
    1. Why is @synthesize statusLabel and using statusLabel not recommended? I have to type less in statusLabel than I do in self.statusLabel, even though in reality Xcode is auto-completing my variable names.
    2. If Xcode is doing @synthesize statusLabel = _statusLabel; then why can't I use statusLabel without getting a build error? I would assume Xcode will add the code above before building my code, so I should be then able to use statusLabel. But that isn't happening here, so I am trying to understand why is Xcode doing @synthesize statusLabel = _statusLabel; at all? 
    Looking forward to your answers.
  • I start with 2) 

    "... , so I should be then able to use statusLabel." Actually, "... , so I should then NOT BE able to use statusLabel"

    Look, " @synthesize statusLabel = _statusLabel; " basically means "instead of actual name "statusLabel" now use another name: "_statusLabel" if you want to access this property directly". 

    So, it kind of "substitution" of name "statusLabel" with the new name "_statusLabel", and so name "statusLabel" does not "visible" any longer per se.  That is why you cannot use name "statusLabel" any more, think of it like it is not exist any longer. It can only be used with "self" like "self.statusLabel"

    Actually, in this case, "self.statusLabel" means "call a setter/getter" to set/get the value, and _statusLabel means "set/get value directly" to this variable. (if you do not know  about getter and setter I think you better read some Objective-C book if you want understand it better)

    2) Just kind of coding conventional, I guess, to make a visible distinction between class properties and variables. 



  • Thanks Tym for filling in some great answers! Like Tym says, there are two forms of @synthesize. The first form specifies a single name for both the property (really the getter and setter methods), while the second form specifies one name for the property and another name for the underlying instance variable that will actually hold the value. For example:

    @synthesize foo; // creates property named "foo" and instance variable named "foo"

    @synthesize foo = bar; // creates property named "foo" and instance variable named "bar"

    If you skip the @synthesize for any declared @property, then Xcode invisibly gives you this:

    @synthesize foo = _foo; // creates property named "foo" and instance variable named "_foo"


    In all of those cases, you can use "self.foo" to get and set the value, which will used the synthesized getter and setter methods. For direct access, you need to use the instance variable's name, which would be "foo", "bar", or "_foo" depending on what you specified.

    I have one simple reason for preferring to always use the implicit definition you get when you skip the @synthesize: It helps me make less mistakes. If you have a property and instance variable both called foo, you might mean to do this:

        self.foo = @"hi";

    but you accidentally do this:

        foo = @"hi";

    Which means that your setFoo: method isn't called. In some cases that's not so important (especially with ARC, since it now automatically takes care of the memory management for you even if you set the instance variable directly), but sometimes it can be *very* important. When the instance variable is _foo instead of foo, then the "accident" above becomes a compilation error. This basically forces me to *think* about what I'm doing, and make a choice about assignment. If I want to call the setter, I use "self.foo = ...", and if I want to bypass it I use "_foo = ...". Using "foo = ..." is no longer an option, and no longer something that I can do by accident.
Sign In or Register to comment.