PrEV
Thoughts from a NeXTStep Guy on Cocoa Development

iVars vs Properties

Mar 11, 2009 by Bill Dudney

While going over some of the errata on the book Chris, Daniel and I spent a bit of time talking about using '_'s in instance variables. It struck me during our conversation that I have not really seen much discussion on naming ivars vs naming properties. I figured I'd blog about it and get your thoughts.

This is how I am currently leaning because it clearly helps me keep in mind the ivar vs the property.

@interface Foo : NSObject {
    NSString *_gak;
}

@property (copy) NSString *gak;

- (void)doSomething;

@end

What I don't like about this is that if I have an ivar that I want to make an outlet in IB (with IBOutlet) then I have an _ on the outlet name in IB. As Ashley points out in the comments though the current recommendation is to have a property for your outlets. Mostly I like that, but I'd also prefer sometimes that getting to an outlet be more difficult than calling a get method. As Brendan points out (also in the comments) though if you have a property you should place the IBOutlet tag on the property rather than the ivar. Semantically they are the same, practically though if you have your ivar and property named differently the ivar's name will show up in IB, which might not be what you want.

In the implementation I do this;

@synthesize gak = _gak;

- (void)doSomething {
  NSLog(@"gak = %@", self.gak);
}

That keeps things nice and clean, I'm always using the get and set methods via the dot notation.

Thoughts? What do you do?



Comments:

With respect to IBOutlet, Apple now recommends that you define @property's for them as well and to place the IBOutlet tag on the @property declaration rather than the ivar.

I believe the reasoning is that the @property declaration explicitly states how and whether the outlets are retained or not.

Posted by Ashley Clark on March 11, 2009 at 10:39 PM MDT #

Where do you put the IBOutlet marker?
It can go on both the ivar declaration and @property:

IBOutlet UITextField *_test;
@property (nonatomic, retain) IBOutlet UITextField *test;
@synthesize test = _test;

but that is not necessary. It can go on either ivar or property. IB will first
search for properties declared as IBOutlet, then ivars tagged as IBOutlet.
Since the synthesize renames it, I thought IB would ignore the private one, but it shows both _test and test.

It is easy to hide, by doing this:
interface {
UITextField *_test;
}
@property (nonatomic, retain) IBOutlet UITextField *test;
@synthesize test = _test;

Dropping the extra IBOutlet is probably better to avoid confusion, since IB will only show the property IBOutlet, and hence memory management will be performed correctly.

Hope that's what you were referring to. With regard to underscore prefix - I think it's a good idea, but often forget to use them :)
Helpful to highlight direct access when coding.

Posted by Brendan on March 11, 2009 at 10:39 PM MDT #

I have just recently started learning Objective-C and Cocoa, so I'm not an expert in this area.
What I do know is that I don't like using the underscore prefix (or other prefixes for that matter).
The reason is that I think its makes the code more difficult to read and “less beautiful” which is an important aspect in general when coding, regardless of the language of choice.

Posted by André on March 12, 2009 at 06:12 AM MDT #

I do use it for any private variables, such as with C++ or C#, as it makes it easy to differentiate. It's actually a defacto standard in the .NET world.

I haven't been doing it in Obj-C; however, I will.

Posted by Stuart Carnie on March 12, 2009 at 06:12 AM MDT #

I name them the same, and use the IBOutlet keyword in the property declaration. The only place where the names "collide" is this class (and possibly subclasses), where the difference between gak and self.gak is evident, and even tokenised differently by Xcode.

Posted by leeg on March 12, 2009 at 06:12 AM MDT #

@Ashley - thanks for the links

@Brendan - updated the entry to clarify the placement of IBOutlet, thanks!

@André - totally agree about the importance of beautiful code. However, in my experience, esp with new ObjC programmers. The addition of the _ helps people to get their heads wrapped around the fact that the ivar is not the same as the property. I like that because the most beautiful code is the code that never references an ivar, all access instead goes through the accessors.

@leeg - new folks have a hard time with this in my experience, despite Xcode more or less coloring the ivar and property differently the difference is not evident

Posted by Bill Dudney on March 12, 2009 at 06:32 AM MDT #

Personally, I don't like prefixing variables because it becomes like Hungarian notation where you encode information about the variables in their name. Then, when you read the code, you're not reading about, e.g. a name, you're reading about an instance variable name, so you're confounding things. I guess this is my take on Brendan's “less beautiful”.

Prefixing instance variables is used in other languages like C++ and Java. However, that doesn't mean it is a good idea, nor that it should be used in Objective-C. Objective-C is derived from Smalltalk which is object orientation done right, unlike the other two (in my opinion). Don't follow procedures in other languages blindly!

I agree that 'properties' has created an issue that prefixing seems to solve. I have certainly been bitten by having a property and ivar of the same name and neglecting to put self. in front. This is also very very hard to debug!!! Personally, I think Apple made a mistake here.

I think that when you look at the idea of object-orientation, the instance variables are of prime importance - they define the nature of the object and its state, and the methods you write are there to use and manipulate those variables. So you shouldn't hide or disguise them.

I don't agree that you should have accessors for every instance variable. What about booleans, integers, floats and the like? Should they have accessors?

Finally (!!), I don't like the use of '_'. If you are going to mark something as special, mark it properly rather than with a mark that might be hard to see (I believe that some people might have a form of astigmatism which makes it even harder). How about using 'the' instead? At least it can be read like part of a story.. theName, theAddress, thePhoneNumber etc.

Sorry for the long comment!

Posted by Karl on March 12, 2009 at 09:19 PM MDT #

Hi Karl,

Great comment, thanks!

Another reason I like the _ is that it helps new people understand that the ivar is not really supposed to be used. In fact on the 'modern' runtime (as someone else pointed out) there are no ivars at all. So in 10.6 or 10.7 when the modern runtime is 'the runtime' we won't even have ivars, only properties.

I think every ivar that is not private and probably even the private one's should have get/set method pairs. Encapsulation, even from yourself, buys you all sorts of good, setting an ivar in a random method (except for very good reason) leaves KVC and KVO hosed. I'd much prefer if we always went through the accessors.

For my 10+ years in java I never used _ because there is very little thought of ivar's being properties or needing encapsulation. The get/set method simply assign and return, no extra goodness to be had. Thus there is no concept of KVC/KVO or anything else that you'd be hosing by simply assigning new values. No reason to use the get/set methods even outside the typical class for the most part. In fact there was quite a debate for a while that all ivars of java classes should be made public to avoid the overhead of calling the get/set methods.

Back in the early 90's when I did smalltalk I never put _'s on the ivars but I always used the accessors, it seemed 'unsmalltalk' not to.

Posted by Bill Dudney on March 13, 2009 at 03:46 AM MDT #

The underscore prefix is pretty common... but one risk that people point to is that Apple also uses it for their ivars, and (as I understand it) there's always the chance that some future API change will introduce a new ivar that will conflict with yours, forcing you to rename it.

Scott Anguish's Cocoa book suggests adding a prefix to all your ivars, so _myGak instead of _gak.

But my preference is Google's convention... which is to append an underscore as a suffix. So gak_ instead of _gak. I find it a bit more readable, plus it's safe from future collisions with the mothership. It doesn't automatically support KVO the way an underscore prefix does... but to my mind private ivars shouldn't be directly exposed anyhow. I'd rather have to declare a property to wrap them.

Posted by Scott Guelich on March 15, 2009 at 04:57 AM MDT #

I wholeheartedly agree that:
a) ivars should be @protected or @private and begin with underscores
b) properties should be sans-underscore
c) IBOutlet types should be on properties only

I find the underscore a reminder in your code that you are directly accessing it, bypassing any possible thread safety, derived value or retain/release behavior.

Posted by Bill Shirley on March 17, 2009 at 04:30 PM MDT #

Apple recommends not using the underscore as a method prefix, because that's what they use to denote their private methods. Imagine if you had a private method that clobbered one of Apples! That would be *terrible* to debug. While the doc doesn't explicitly say this, I'm sure that the same holds true for ivar names.

Apple documentation
Cocoa Dev on naving conventions
Variable names on Cocoa Dev Central

Posted by Dave DeLong on March 21, 2009 at 02:49 PM MDT #

Hey that is exactly what I posed in October already ...

http://forums.pragprog.com/forums/83/topics/1201#posts-5571

Except I use 'boost style' variables with the underscore at the end.

Posted by Stefan Arentz on March 21, 2009 at 02:49 PM MDT #

Would you mind explaining in more detail? I'm new to Cocoa and I thought you *had* to name the ivar and the property the same thing. Isn't a property just a way of defining get/set methods on a previously defined ivar? I don't understand how having a property without a corresponding ivar would even work, since the property sets up the get/set methods on a variable that doesn't exist if they have different names.

Thanks in advance for any clarification.

Posted by Elisabeth on July 05, 2009 at 11:14 PM MDT #

Hi Elisabeth,

In the 64 bit runtime the storage is created dynamically at run time instead of being backed into the class at compile time. That is how the compiler is going to be able to get rid of ivars.

The properties are a way to declare (and implement via @synthsize) get/set method pairs.

Hope this helps, if not please repost.

Posted by Bill Dudney on July 05, 2009 at 11:14 PM MDT #

Post a Comment:
  • HTML Syntax: Allowed