iPhone ivar naming convention [duplicate]
Asked Answered
V

7

22

Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?

I've noticed that in a lot of the reference materials out there, I see that a lot of the time, variables are named _variable in the .h file, then are @synthesize'd in the .m file as

@synthesize variable = _variable;

Why is this done? What am I missing?

Thanks!

Vacillating answered 22/1, 2010 at 2:33 Comment(1)
I've seen ivar_ being used instead of _ivar also, but I can't really form an argument for them except that they look better...Ilk
K
21

There is not consensus on this. Some people like to use it for clarity to separate out class variables, and as another responder noted to avoid conflict with incoming parameter names. Even in Apple sample code the use is mixed.

However, I greatly prefer to not use the _ prefix and have two strong reasons:

1) Some people think the _ is a good indicator of "private". My take is that NO class local variable should be accessed without a setter/getter (property) and thus they are ALL private - given that why not name them in a way easier to read and use autocomplete on? Any overlap in names from parameters is quickly revealed by the compiler, and avoided through more thoughtful naming of parameters (or internal variables).

2) (even better reason) - if you use "refactor" in XCode on an internal class var that is named the same as the property used to access it, the property and synthesize statement will also be renamed. If you use refactor on a class variable prefixed with an _, the property name will not be changed - just the synthesize mapping to the internal name. I pretty much never want the name to vary from the property to the real variable it exposes access to. That alone makes me never want to use _ as a variable prefix, since being able to shift names is just about the most useful thing you can do to improve code clarity.

Knutson answered 22/1, 2010 at 6:41 Comment(3)
Any suggestions on naming method parameters so they don't clash with ivar names? This is especially acute for initWith* or manually implemented property setters. I've tried "a/an" and "new" prefixes for awhile, but it's not always convenient (like when a name is in plural). I've also tried underscore prefixes for parameters but this is easy to drive code readers crazy because of Apple's and dev community preferences to use underscore with ivars. To some extent this applies to underscore suffix as well.Cheney
These days I use "_" prefixes for all internal class vars (opposite I know!) because I only use them with properties - and since the properties automatically create iVars with _ as a prefix I stick with that. Refactor works on properties, and with properties you never see the name so the "_" doesn't really matter. It also eliminates the overlap problem you have. I'll edit this answer to reflect my new thinking at some point.Knutson
I see. I am still personally hesitant to access my own ivars via properties though (e.g. more like _ivar/ivar vs self.ivar): don't like having public writable properties or redeclaring read-only properties as writable in .m. But as you said, there is no consensus :)Cheney
D
15

Using that syntax is an option to make it more clear that the ivar and property are different things.

To code external to the class, there is no difference since it uses the property.

For code in the implementation of the class itself, it can make it more clear when the ivar is used versus the property.

For example, say we have an ivar/property for an NSNumber object:

@interface MyClass : NSObject {
    NSNumber *num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end

@implementation MyClass
@synthesize num;

- (void)doSomething {
    // set the property, num is properly retained
    self.num = [NSNumber numberWithInteger:1];

    // accidentally set the ivar, num is NOT retained
    num = [NSNumber numberWithInteger:2];
}
@end

and now using a different name for the ivar and property:

@interface MyClass : NSObject {
    NSNumber *i_num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end

@implementation MyClass
@synthesize num = i_num;

- (void)doSomething {
    // set the property, num is properly retained
    self.num = [NSNumber numberWithInteger:1];

    // compiler error, there is no ivar named "num"
    num = [NSNumber numberWithInteger:2];

    // set the ivar, so it needs to be a retained object
    i_num = [[NSNumber alloc] initWithInteger:3];
}
@end
Deutero answered 22/1, 2010 at 5:19 Comment(0)
L
9

Previous answers are missing the history behind this. Before Objective-C 2.0, there were no properties. So you’d have an object with instance variables like this:

@interface MyObject: NSObject {
    NSArray *myArray;
}

@end

But how would you access them from other objects? the solution was to make setters and getters. But to avoid confusion, they would do it like this:

@interface MyObject: NSObject {
    NSArray *_myArray;
}

- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;

@end

The _ serves to clear up confusion between the instance variable _myArray and the method -myArray.

Lacteal answered 13/1, 2011 at 22:37 Comment(3)
I am not sure how keeping the ivar name without an underscore would be confused with the myArray method name. Not by the compiler at least. Calling a method [obj myArray] or referring to its selector @selector(myArray) was always different from referring to its ivar (obj->myArray or simply myArray or self->myArray from own methods).Cheney
It’s more for when you’re in an instance method of a class. It’s easy to accidentally write myArray = @[@"A", @"B", @"C"]; instead of myArray = @[@"A", @"B", @"C"];.Lacteal
OK, I understand. I guess you meant it's easier to mistype myArray = ... when meaning self.myArray = ....Cheney
M
4

Sometimes people use mVarName (C++) and in Obj-c the style seems to be _varName. One problem you can have, is imagine that your argument to a function is ...set:(int) x - BUT - you have an iVar called x...well your going to get the compiler crying about stuff like that - not to mention its confusing.

The m,_, whatever helps to show what are member properties of the class.

 -(void) set:(int)x
{
 x = x; // x is an ivar! heh
}

VS

 -(void) set:(int)x
{
 _x = x; // ahh I see!
}
Maunsell answered 22/1, 2010 at 2:39 Comment(0)
B
1

I prefer not to use the '_' prefix because Apple does use it consistently. By avoiding the prefix I then have greater confidence that my ivars do not collide with Apple's when I extend a cocoa touch class. Since we do not have access to the base class' source this is really the only way I know of to avoid accidental reuse of existing private ivars.

Much like

Method names beginning with “_”, a single underscore character, are reserved for use by Apple.

Bonanno answered 13/1, 2011 at 22:33 Comment(0)
A
0

This is purely convention. I suppose its common because when you make a method getter call like this:

[myObject variable]

you are actually calling a method, not accessing a variable directly. the _ in front makes it clear that you are talking about a variable. Personally, I find this syntax annoying and distracting. I find it unnecessary, but you are right, it does appear here and there.

Arched answered 22/1, 2010 at 2:38 Comment(0)
U
0

My preference, following Google, is simply to append an underscore and explicitly synthesize (even if I'm reimplementing):

@synthesize varName=varName_;

If I see that trailing underscore outside of init..., dealloc or an accessor, I know something's fishy.

Unmeasured answered 23/3, 2011 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.