Properties

Discussion in 'iOS Programming' started by MickeyT, Jun 25, 2012.

  1. MickeyT macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #1
    Hello

    I am a programming novice so apologies if my questions are daft. I have some experience programming with VBA, which I think is where some of my confusion comes from when trying to reconcile how things works with how I understand it works in VBA.

    I am trying to understand the role properties play. In VBA, my understanding of a property is it sits over the top of a privately declared variable in order to exercise some control and validation over the assignment of a value to the underlying private variable. Therefore, the private variable has to be declared and then getters and setters are written to deal with the assignment.

    When reading about how to do it in Xcode (or should that be objective c?) it doesn't seem like the underlying variable has to be declared - if you put the appropriate @property code in the header and the @synthesize code in the implementation file, the underlying variable presumably must get created in the background?

    However, when I was reading about setting up a view controller with any necessary outlets, you declare the IBOutlet objects and then also write them out with the @property syntax in order to generate their getters an setters, so in this case the variables are declared in addition to the property code.

    Can anyone explain the role of properties and how they work please, first of all, in as straightforward a manner as possible?

    Thank you in advance.
     
  2. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #2
    First of all, Xcode is the IDE, so yeah, Objective-C is the language.
    Properties are basically public objects, so if you declare a property in your header, it will open them up to other controllers to manipulate them (depending on their options), there is no need to declare an ivar & redo it in the properties, me and myself find this highly irritating, because most people forgot the difference between self.nameOfObject or nameOfObject, one does refer to the property while the other is the ivar, this is highly confusing code to read.
    So I prefer to just make a property (you can make these private if you declare them in a private interface in the M file). Because @synthesize basically generates the getter/setter.
    This is a short introduction, I think PhoneyDeveloper or so can give you a more in depth explenation..
     
  3. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #3
    Thanks for the reply.

    What's an ivar? Is this the underlying variable (if you have created one as opposed to just creating the property)?
     
  4. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    I believe that's correct. (Honestly, I sometimes get confused, too.)
     
  5. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #5
    Okay, so here's the next point of confusion:

    Is a property just a method that assigns something to a variable (unless you override it and get it to do something else before doing that). In fact, a getter is really a method that returns something (i.e. the "get" part) and the setter is a void method (because you set it to something and don't want an answer returned)?

    If so, are properties just a convenience to have in place of methods when you simply want to assign values to variables?

    And, if so, if you decide to override a property to do more than this then what's the difference between that and just writing a method. Presumably just syntax:

    Code:
    myString = [myObject getText]
    versus

    Code:
    myString = myObject.text
     
  6. chown33, Jun 25, 2012
    Last edited: Jun 25, 2012

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    See the Declared Properties section of The Objective-C Programming Language guide.

    Then read the entire guide. The Introduction section has links to other docs under the "See Also" heading.
    If you have never used object-oriented programming to create applications, you should read Object-Oriented Programming with Objective-C. You should also consider reading it if you have used other object-oriented development environments such as C++ and Java because they have many expectations and conventions different from those of Objective-C.

    If you have questions about something in the Language guide, or any other Apple document, feel free to ask them. Reading a guide is better than guessing.


    In your first post, you said you were reading about Xcode. What were you reading? A book? A tutorial? An online Apple reference doc?
     
  7. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #7
    Declaring and synthesising a property automatically creates an ivar, since Xcode 4. The default name of this ivar is the name of your property.
     
  8. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #8
    IVAR = Instance variable, you can connect properties to ivars, but I tend not to.
    I rather just create my stuff like this: code example for ohters:

    Code:
    @interface SPMainMenuVC () 
    {    
        IBOutlet UIView *adminView;
        IBOutlet UIView *staffView;
    
        /* Custom Label */
        IBOutlet FontLabel *nameLabel;
    
       [B]Here I just create some random stuff I will only be using as outlets and won't be modifying too much.[/B]
    }
    
    @property (nonatomic, retain) SPUser *loggedInUser;
    [B]I just create a property which will be available with self.loggedInUser, if you put the property in your header, this is also public available and modifyable from there.[/B]
    - (void) buildSideBar;
    [B]Private methods, so you can't call them from other classes implementing this class.[/B]
    
    @end
    
    @implementation SPMainMenuVC
    @synthesize loggedInUser = _loggedInUser;
    [B]I just do _loggedInUser, this makes it possible to ONLY call self.loggedInUser, and not call the ivar loggedInuser, that they are talkinga bout earlier, I used to do this before ARC, because then I knew that I retained it and nothing else.. Maybe this isn't necessary anymore in ARC.. But I use it for myself[/B]
    
    Hope I made that clear, i'm not saying that I write the cleanest code or whatever, we in the company just started making some rules so we can easily debug stuff, like having the private properties/methods etc.
     
  9. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #9
    Yes, these are functionally identical, though usually the method name would be -text rather than -getText. The main issue with accessing a property rather than just using the ivar directly is KVC/KVO: when you use the accessor to set a value, other objects as observers are able to receive notification of changes and act accordingly; this is how bindings work.

    Properties by default are "atomic", which means that the synthesized functions are enclosed by a thread coherency lock (they are thread-safe). This can add some execution overhead. If you have no worries about thread safety (e.g., your app is not multi-threaded), you should probably add the "nonatomic" attribute to a property declaration if you expect it to be accessed heavily.

    Apple seems to want to push the property idea. Their documentation is replacing methods with properties, which makes the text much more concise.
     
  10. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #10
    This is really helpful, albeit it seem like an awful lot is going on just to be able to refer to something with "self." before it rather than using the square bracketed approach. Whilst I am aware it is good practice to refer to variables by their property, even if the reference and the ivar are inside the same class, I'm kind of struggling to see the usefulness.

    If I have a class containing a load of private variables, I can absolutely see the worth in having properties which someone who creates an instance of the class can use to assign values to the underlying private variables. This allows you to validate what is being assigned, perhaps perform some other tasks before going ahead and doing the assignment.

    However, I can't see the point in having properties referring to public variables - surely that defeats the point?? Why use the property if you can go straight to the variable?
    Maybe this is where Sydde's point comes in?

    So, in summary; if I create a class and create some properties in the header file, when someone creates an instance of my class, they can use the properties to interact with my private variables in a way I can control. For example:

    Code:
    Header File
    
    @property(nonatomic) double myDouble;
    
    /*The nonatomic might be wrong, but I'm trying not to concern myself with this aspect just now*/
    Code:
    Implementation File
    
    @synthesize myDouble = _myDouble;
    If someone created an instance of my class, they would be able to do things like:

    Code:
    classInstance.myDouble = 2;
    or

    Code:
    anotherDouble = classInstance.myDouble
    If this is right then am I right in saying:

    a) they would never be able to reference the underlying ivar, primarily because it is never separately declared?
    b) if I had done this via creating an ivar double and not creating a property, I'm guessing they would still have no access to the ivar, unless I wrote a method that allowed for that?

    Thanks everyone for the responses by the way.
     
  11. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #11
    I am floundering around a little bit reading lots of things trying to gain some traction.

    Currently, I have:

    - Sams Teach Yourself iPhone Development
    - iTunes U Stanford iPhone course
    - These forums
    - Previous reading C# book which was very good and was what led to me understanding OOP
    - The stuff I do at work with VBA

    I am fully aware that VBA is heavily sanitised, but I think I've done reasonably well to teach myself to write things with classes, userforms, interfaces etc without any tuition. That has come from doing and then looking up solutions or asking someone when I've got stuck. I figured I could try the same approach with this and it will eventually come.

    I also started the iTunes U Stanford CS106A course, spent £60 on the book, and then started to feel like it was heavily biased towards graphics. I am comfortable with form based applications because they are akin to my experience with VBA, so I found understanding how to make a GOval bounce around the screen like a beach ball pretty tough.

    I feel like its time to actually sit down and have a go rather than continually reading and not doing, and ask questions when I hit an obstacle. Invariably every time I pick up a book the first few chapters generally comprise all the same stuff; I must have read about data types, programme flow control, classes, inheritance and encapsulation a million times now.

    The other major issue I'm having is not knowing how to use core data, so any practice apps I create run out of steam pretty quickly because I don't know how to store a lot of data. I can only do so much before not knowing how to store data limits the complexity of what I can have a go at.
     
  12. MattInOz macrumors 68030

    MattInOz

    Joined:
    Jan 19, 2006
    Location:
    Sydney
    #12
    What might help is to find an old pre-Objective-C 2.0 tutorial.
    Like this one that references a 2004 book.
    http://www.otierney.net/objective-c.html

    Prior to the introduction of @property and @synthesize you had to manually create a lot of lines of code that sounds like it could have been similar to how you describe VB.

    @property is a compiler instruction to generate those lines of code for you in the interface file (.h). @synthesize generates the code in the implementation file (.m).

    Apple have done a lot with Objective-C and the SDK over the last few years to reduce the amount of code you need to type, but it's mostly backwards compatible. If you get stuck it can be good to go back to old tutorials and see it in the raw long form.
     
  13. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #13
    That link is brilliant. Thank you!

    I reckon I'm just about there now and can leave this alone for the moment.

    I probably just want to clarify one last thing:

    Why are the objects on the view declared separately from their associated @property code:

    Code:
    
    IBOutlet UITextField *myTextField;
    
    @property(nonatomic,retain) UITextField *myTextField;
    
    
    Is this because if it were left to the @property line to create the class instance in the background there would be no way to declare what that UITextField was the outlet of on the view (I.e. the IBOutlet bit)?
     
  14. Ron C macrumors member

    Joined:
    Jul 18, 2008
    Location:
    Chicago-area
    #14
    They don't have to be anymore, I think it's more a backwards compatiblity style. I'd say you're looking at pre-ARC code; with ARC and some other changes, you really don't have to do a lot of this anymore.

    As for the IBOutlet bit, you can directly declare a property as an IBOutlet by doing:
    Code:
    @property (nonatomic, retain) IBOutlet UITextField *myTextField;
    I do this all the time, and in XCode 4.3.2 you can control-drag from a IB item to the corresponding code file (being shown in the Assistant editor) and it will create the property for you, provide the link between that property and the item, and generate appropriate code in the .m file to synthesize it and release it in viewDidUnload (I think that's where it puts it).

    One of the things I do in my code (and you see it quite a bit in other code as well) is make sure that the the ivar (or generated ivar) is NOT named the same as the property, thus letting the compiler let me know if I do something unintentionally.

    For example, using the above myTextField property, in the .m file I would have:
    Code:
    @synthesize myTextField = _myTextField;
    
    What this says is essentially: make 2 methods, -(UITextField *)myTextField; and -(void)setMyTextField:(UITextField *)myTextField, and populate them thusly:
    Code:
    -(UITextField *)myTextField
    {
        return _myTextField;
    }
    
    -(void)setMyTextField:(UITextField *)myTextField
    {
        [_myTextField release];
        _myTextField = myTextField;
        [_myTextField retain];
    }
    
    There's a lot more of pedantic stuff that's important to know if you're working on the compiler itself, but as a user of the compiler this is sufficient to get a working view of what's going on.
     
  15. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #15
    Ah, that makes sense then.

    Does this have to go between the @interface curly braces, or should it sit outside them? As in:

    Code:
    @interface ViewController : UIViewController {
    
        @property(nonatomic,retain) IBOutlet UILabel *aLabel;
    
    }
    
    -(void) aMethod;
    
    @end
    versus

    Code:
    @interface ViewController : UIViewController {
    
    }
    
    @property(nonatomic,retain) IBOutlet UILabel *aLabel;
    
    -(void) aMethod;
    
    @end
    In the former, I would have put the IBOutlet object between the curly braces and the property outside, but if I can just write it all in one line, where does the property statement sit? Would it be outside - I'm guessing that when I go to link the label in interface builder that it will still see the UILabel object even though it has been declared outside the curly braces because I have done it this way?
     
  16. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #16
    Instead of guessing, please consult the Objective-C language guide I previously linked to. That's why I linked to it; because whatever you were reading at the time didn't seem to cover what you were trying to do.
     
  17. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #17
    Sorry, I didn't have time to visit your link when I read your post and then completely forgot to go back to it.

    I can see the answer to my question straight away:

    Thanks everyone for your help on this.
     

Share This Page