My rookie’s confusion with Objective-C properties

When I started coding in Objective-C, one of the first things I learned about was properties. The tutorials I worked from showed me properties before talking about instance variables. In fact, they didn’t go into much detail about instance variables, so you’ll forgive me for starting out thinking that properties were instance variables.

It wasn’t even a problem until I made a sub-class that needed to use one of its super-class’s properties. It didn’t think the property existed. I thought maybe the problem was that the property was only synthesized in the super-class, so I tried copying the “@synthesize” line into the sub-class’s implementation. It seemed to work at first, but it turns out it was just creating a new property. It didn’t get or set the same data that the super-class was referring to.

Of course, what I was missing is that the whole point of properties is not to make a place to store data. You can do plenty of data storage with simple instance variables in the “@interface” block like so:

@interface Class : SuperClass
{
ObjectClass *myData;
}

You use properties when you want to give outside objects access to data, and all properties do is automatically create method to get and set instance variables. So I could write an object like this:

@interface Class : SuperClass
{
ObjectClass *_myData;
}

- (id)myData;
- (void)setMyData:(ObjectClass *)myData;

Or I could get the same result by writing this:

@interface Class : SuperClass
{
ObjectClass *myData;
}

@property myData;

Now when you write “@synthesize myData;” in your implementation file, you should think of that as the same as defining two methods, “myData” and “setMyData”. In fact, if you don’t write a “@synthesize” line and just start typing “- (void)setM”, Xcode will want to finish it as “- (void)setMyData” because declaring the property in the interface sets us up to expect getter and setter methods in the implementation. You can even leave “@synthesize” out of it and define the methods by hand, if you want. That can be convenient if you need extra stuff to happen when outside objects get and set your properties. Which leads me to another thing that confused me. When you define a property, you’ve also got options like this:

@property (assign) myData;
@property (readOnly) myData;
@property (retain) myData;

What’s the difference? The difference is what kind of setter method you’re automatically defining. “(assign)” gives you straight up assignment. “(readOnly)” doesn’t let you set at all. “(retain)” does the extra magic to manage the memory for your property. This is where properties get really nice. You can make sure your object is getting retained and released at all the right times if you use “(retain)”. And you can be sure that when you assign your property with a brand new object, the old one will be disposed of correctly. When you deallocate, you don’t release this kind of property. Instead, you just assign it to nil. Your synthesized setter method will do the rest.

Tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>