When do you make an underscore in front of an instance variable? [duplicate]
Asked Answered
P

8

30

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

I've seen this at Apple, inside UIPickerView.h:

id<UIPickerViewDataSource> _dataSource;

why's that underscore there? Does it have a special meaning? A Convention I must know about?

Periwinkle answered 7/5, 2009 at 23:28 Comment(1)
#822987Zwiebel
U
34

A lot of people use this for private variables, to differentiate between private variables and public variables within an object.

It is a completely optional way of working.

Unconformity answered 7/5, 2009 at 23:31 Comment(10)
Apple reserves variables starting with _ for its own uses. Don't do it.Larkspur
I'd +1 gs's comment if I could.Hemihedral
@gs (or Abizern): Do you have a reference for this? I know the compiler uses the C standard name mangling, which will add an underscore, but that doesn't prevent you from doing this in your own code base as well...Unconformity
gs is incorrect, instance variables starting with _ are fine. Method names starting with _, however, are reserved by Apple.Cheriecherilyn
I trust Chris, he would definitely know. My rule is to be cautious about naming (with or without underscore) when subclassing, particularly if you happen to subclass code from Apple or third party.Spiegel
My (limited) experience is: If you subclass one of Apple's classes, and add an instance variable that collides with one of the superclass' private ivars, Xcode usually warns you (regardless of the presence of the underscore). I have submitted code formatted this way (i.e., ivars start with an underscore) and have not been rejected so far.Kamal
I'm all for underscores. They provide clarity and a distinction between ivars and properties. More than once I tried to add an instance variable that started with an underscore, when subclassing one of apple's classes, and Xcode gave me an error ('redefined ivar'). If your ivar's name collides with one of Apple's, Xcode will let you know (and you can change the name, or use the existing property).Kamal
I know that _underscore is reserved by Apple. I heard it myself, from Apple engineers at the WWDC, however does anyone know where I can find an official document or guideline on Apple.com? I need some sort of proof to convince my team.Edging
@hs: Chris Hanson is from Apple, and he does know, scout's honor. Leading underscores are reserved for method names, NOT ivars. (If you run afoul, the compiler will keep you honest.) Using a construct like @synthesize var = _var; also (gently) guides you toward using accessors and dot notation constructively.Actinouranium
@hs: Actually ... as for convincing your team, note that Xcode 4 already does this with its templates. See also: Declared Properties and Instance Variables - Coding Guidelines for Cocoa.Actinouranium
H
28

What you're seeing is the use of underlines to distinguish between instance variables and properties. So a class declaration might be:

@interface Foo {
  NSString* _label;
  ....
}

@property (nonatomic, retain) NSString* label; // notice: no underline

Then in the implementation file you would have:

@synthesize label=_label; // the property is matched with the ivar

Now when inside the implementation, if you want to access the instance variable directly you could just use _label but to go through the property accessor methods (which take care of retain/releases and a bunch of other book-keeping tasks) you would use self.label. From the outside, you would always want to go through the {object}.label property.

The other way is to do without the underline and just use:

NSString* label;
@property (nonatomic, retain) NSString* label;
...
@synthesize label;

It works the same but then it might confuse someone reading the code and trying to keep track of label vs self.label. I personally find the Apple convention (with underlines) a bit easier to read but it's a matter of preference.

Hautesalpes answered 8/5, 2009 at 5:13 Comment(4)
Thanks. Personally, I don't like that underline-mess ;)Periwinkle
Not entirely — people use "" in any number of programming languages, and did so in Objective-C long before properties were added. This is only one possible use, but there are many others. Some people prefer to use "" for all instance variables, or only private variables, or whatever. Personally, it's not my style either.Spiegel
I just spent ages tracking down a memory management issue due to a variable not being retained since I was using timer instead of self.timer. After this experience, I strongly recommend the use of an _ in front of all private variablesCoupling
Thanks for this explanation, I was baffled myself. All clear now.Bushbuck
I
8

As people said already _someVar was used to say that a variable was private. It was a simple matter of convention and doesn't really matter.

One other use, taking a trip in the wayback machine in C a _function() represented a function that wasn't platform portable and __function() represented a function that wasn't compiler portable. So, in the standard C library, you will sometimes see a variable with a _ or __ infront of the name, this is what those functions represent.

Inkhorn answered 8/5, 2009 at 0:28 Comment(1)
I guess that's where _asm and __asm come from?Kamal
C
2

It's sometimes used to denote private variables. More generally it just means "this variable is different somehow".

Columbus answered 7/5, 2009 at 23:32 Comment(0)
E
2

can it be that... (jogging memory)...

i vaguely remember reading an ADC document explaining that apple reserves the usage of underscore-prefixed member variables? and that 3rd party developers are discouraged from using this convention so as to avoid collisions?

|K<

Epitome answered 8/5, 2009 at 14:6 Comment(3)
Collisions? When subclassing? That might make sense.Periwinkle
Incorrect. It is underbar-prefixed method names that are reserved, not instance variable names. (Objective-C doesn't use the term "member.")Cheriecherilyn
@chris: thank you very much for clearing this up for me.Epitome
G
2

I use underscores to denote that a variable is a member, similar to the 'm' prefix in Hungarian notation (which notation I despise thoroughly, but that's another story). Sure you get colour-coding editors these days, but my opinion is that the prefix makes you think about the variable being a member/instance one before you type it, not just sometime afterwards when it gets colour-coded by your editor.

Gemination answered 9/5, 2009 at 0:12 Comment(0)
G
1

Generally it's to denote that a variable should not be directly touched by a developer. It's not really a requirement but it's good practice if you can't avoid having a public variable in a class that you don't want messed with.

Gripper answered 7/5, 2009 at 23:33 Comment(1)
There is the @private keyword for instance variables in a class implementation that does this.Hemihedral
K
1

I choose to use underscores for ivars because I often come across the following situation:

@interface MyClass:NSObject
{
    NSUInteger count;
}

@property(nonatomic) NSUInteger count;  

-(id) initWithCount(NSUInteger) count;


@end

(...)

@implementation MyClass
@synthesize count;

-(id) initWithCount(NSUInteger) count
{
    if((self = [super init])){
        self.count = count; // Parameter name collides with ivar name!
    }
    return self;
}

@end

So I do this:

@interface MyClass:NSObject
{
    NSUInteger _count;
}

@property(nonatomic) NSUInteger count;  

-(id) initWithCount(NSUInteger) count;

@end

(...)

@implementation MyClass
@synthesize count = _count;

-(id) initWithCount(NSUInteger) count
{
    if((self = [super init])){
        _count = count; // No name collision
    }
    return self;
}

@end

Of course, I could alternatively change the parameter name to "newCount" or "aCount" (I hate that one). I think it's a matter of taste.

Kamal answered 30/1, 2012 at 7:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.