58

I've previously avoided underscores in my variable names, perhaps a holdover from my college Java days. So when I define a property in Objective C this is what I naturally do.

// In the header
@interface Whatever
{
    NSString *myStringProperty
}

@property (nonatomic, copy) NSString *myStringProperty;

// In the implementation
@synthesize myStringProperty;

But in almost every example it is done like

// In the header
@interface Whatever
{
    NSString *_myStringProperty
}

@property (nonatomic, copy) NSString *myStringProperty;

// In the implementation
@synthesize myStringProperty = _myStringProperty;

Should I get over my aversion to the underscore because that is the one way it should be done, is there a good reason for this style being the preferred one?

Update: With automatic property synthesis nowadays you can leave out the @synthesize and the result is the same as if you'd used

@synthesize myStringProperty = _myStringProperty;

which clearly shows you Apple's preference. I've since learned to stop worrying and love the underscore.

Michael Behan
  • 3,433
  • 2
  • 28
  • 38
  • 10
    A link to the original question that you think this one duplicates would save future searchers some time. – user2067021 Feb 29 '16 at 01:28
  • Maybe this?: [How does an underscore in front of a variable in a cocoa objective-c class work?](https://stackoverflow.com/questions/822487/how-does-an-underscore-in-front-of-a-variable-in-a-cocoa-objective-c-class-work) – Ben Butterworth Jun 04 '21 at 11:02

7 Answers7

50

I always use underscores. It creates a clear distinction between local variables and instance variables. It also avoids compiler warnings in the following situation:

@interface MyClass
{
    NSString *name
}

@property (nonatomic, copy) NSString *name;

- (id) initWithName:(NSString *) name;
@end

@implementation MyClass

@synthesize name;

// The following method will result in a compiler warning
// (parameter name same as ivar name)
- (id) initWithName:(NSString *) name {
   if (self = [super init]) {
      self.name = name;
   }

   return self;
}

@end

EDIT:

After having to endure downvotes and reading through the comments, let me try to make my point:

Apple recommends that ivars have the same name as their property. Apple also recommends that properties start with a lowercase letter. And Apple also recommends that local variables start with a lowercase letter.

Now you have a problem, because when you read a piece of code, and you see a variable being used, you cant' tell by the naming convention if this variable is an ivar or a local variable. That sucks. The solution is to have different naming conventions for ivars and local variables. That's just plain common sense.

The way you implement this naming convention is irrelevant. If you really want, you can simply append "_WOOHAHA" to the ivar names. I don't care (but maybe others will). The thing is that people who know what they're doing have decided to go with the "underscore prefix" for ivars. IMHO, they made the right decision, even if their own company recommends something else. (the developers I'm talking about are the people writing some major Apple frameworks and the .NET Framework classes)

In the end, code quality is more important than following a stupid rule that isn't even followed by the people preaching it.


Another remark about the code you've shown: never use retain on string properties. You should use copy instead.

For more info about copy/retain on properties, see:

NSString property: copy or retain?

Community
  • 1
  • 1
Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
  • 5
    It's not about that. It's about the naming conventions. When you see code that uses a variable that is prefixed with an underscore, you know right away it is an ivar, and not a local variable. Apple does it that way, and Microsoft uses this convention in the complete .NET framework code. – Philippe Leybaert Aug 19 '10 at 11:47
  • Thanks for pointing out the retain/copy mistake in the code. – Michael Behan Aug 19 '10 at 12:02
  • I guess it is not a common convention, just have a look at Apple sample code. If you mean that it is used in Apple's own code, it does not mean it is standard for the reason above. – rano Aug 19 '10 at 12:13
  • 4
    I didn't say it was a standard. I said "I always use underscores because...". I've had it with Apple and Microsoft preaching coding practices that are flawed. They tell us to do things a certain way, but for their own code, they use a different (better) standard. Any coding practice that leads to less confusion and a better understanding/readability of the code is the right choice. – Philippe Leybaert Aug 19 '10 at 12:31
  • So I add that this practice is less readable that putting an article before the local variable name. Plus in C99 it is used for reserved variables http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – rano Aug 19 '10 at 12:36
  • 1
    @rano: In C99, only identifiers that begin with an underscore and an *uppercase* letter are reserved, or identifiers that begin with two underscores. – dreamlax Aug 19 '10 at 13:07
  • @dreamlax: on that link they said: "All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces" after saying what you said – rano Aug 19 '10 at 14:53
  • @rano: no matter what the C99 specs say (which may be correct), apple uses the "prefix with underscore" convention for all their UIKit code. Just check any header file for UIKit classes, and you'll see. Having a distinctive naming convention for ivars is simply common sense, even if it's "officially" not recommended. If you do it by prefixing with an underscore, or adding "_WOOHAHAH" as a suffix is irrelevant. – Philippe Leybaert Aug 19 '10 at 22:28
  • @rano: ivars do not have file scope, so you can use underscores for them if you so wish. – JeremyP Aug 20 '10 at 07:50
  • @Philippe Leybaert: First let me say that I think the down vote was harsh. However, naming conventions are just naming conventions. If somebody comes along who didn't know your naming convention, then it's just meaningless fluff to them. Far better to choose local variable names that don't clash with your ivar names. – JeremyP Aug 20 '10 at 07:54
  • 2
    Oh and by the way, *I* know what I'm doing and I don't use the underscore prefix. Also, it's an unsafe assumption that Apple engineers do know what they are doing just because they are Apple. – JeremyP Aug 20 '10 at 07:56
  • 1
    @JeremyP: you are right but adopting that naming convention in a language that is a superset of C can lead to less readable code. This is my point through the start when someone was arguing it was useful for distinct local variables from ivars in order to avoid compiler warnings – rano Aug 20 '10 at 07:57
  • @rano Avoiding compiler warnings is the least of my worries. It's just a matter of code readability. Having a clear distinction between ivars and local vars can make a big difference. And @JeremyP: of course, if you don't know about the used naming convention, it's of no use to you, but you're usually working on a project where you know the adopted naming convention. But as has been said before: it's all a matter of preference. – Philippe Leybaert Aug 20 '10 at 09:18
  • @Philippe Leybaert: code readability shall mean the property of a piece of code to be easily read by 'someone', even someone other that you. As said before there are better ways to achieve that without making confusion between local variables and ivars – rano Aug 20 '10 at 09:31
  • I don't agree. Let's leave it at that. – Philippe Leybaert Aug 20 '10 at 12:56
  • In case anyone is still wondering if this is the right thing to do, check out how Apple decided to implement auto-synthesized properties. – Philippe Leybaert Dec 06 '12 at 21:13
29

The naming convention for the instance variable prefixed by _ is now clearly stated by Apple in the "Coding Guidelines for Cocoa", after the revision of 2012-02-16, with its reason.

Make sure the name of the instance variable concisely describes the attribute stored. Usually, you should not access instance variables directly, instead you should use accessor methods (you do access instance variables directly in init and dealloc methods). To help to signal this, prefix instance variable names with an underscore (_), for example:

@implementation MyClass {
    BOOL _showsTitle;
}

If you synthesize the instance variable using a declared property, specify the name of the instance variable in the @synthesize statement.

@implementation MyClass
@synthesize showsTitle=_showsTitle;

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE

The lecture in iTunes U, iPhone App Development CS193p Fall 2011 taught by Paul Hegarty at Stanford University, also explains this convention.

http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255

I'm aware of that this question is asked quite a while ago, but I myself had the same question and wanted to share my findings.

Taka
  • 1,334
  • 17
  • 24
18

Current suggested Objective-C 2.0 practice is to use the same name for the ivar as the property. You can optionally assign a different ivar in the @property declaration, but the fact that by default, synthesized accessors for a property will access the ivar with the same name as the property indicates that's the pattern they expect you to follow.

No matter what, since objects still have to send messages to themselves to access properties, it's hard to confuse when you're accessing a property or when you're accessing its backing ivar directly, though using the 2.0 dot access to properties does make it more possible. Using the standard message passing syntax makes intent more explicit, IMO.

@interface Foo : NSObject {
     NSNumber *bar;
} 
@property(readwrite, retain) NSNumber * bar
@end

@implementation Foo 
@synthesize bar;

-(void) baz {
   NSNumber *numberOne = [NSNumber numberWithInt: 1];   
   //Both set the value of bar through either the your custom or the synthesized setter method
   [self setBar:numberOne];  
   self.bar = numberOne; 

   //Both get the value of bar through your synthesized or your custom accessor method
   NSNumber *fooBar = [self bar];
   fooBar = self.bar;

   //Both manipulate the bar ivar directly
   bar = numberOne;
   fooBar = bar;
}
@end 
Emil
  • 7,220
  • 17
  • 76
  • 135
mlwelles
  • 307
  • 2
  • 4
6

Apple reserves selectors beginning with underscore for their own "private" methods and that would include properties. I don't think they reserve _ for ivar names though.

Personally, I would steer clear of using underscore to start any kind of variable name. It's an opaque convention. What if somebody else uses underscore for locals and no underscore for instance variables? What if you accidentally omit the underscore in a method where you have a local defined with the same name?

It's much better to make your local names different from your ivar names. For example in a setter you might use newName or neWValue.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Please have the courtesy to leave a comment if you downvote – JeremyP Oct 12 '10 at 13:56
  • @Yar: What are you referring too as being "no longer true or never was"? – JeremyP Aug 22 '12 at 07:17
  • @Yar OK, well in 2010 when I wrote the post, it was true that Apple reserved selector names prefixed with underscore for their private methods. In fact, I have just checked and this is still true. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-1003829-BCIBDJCA – JeremyP Aug 22 '12 at 14:06
  • @Yar And I never said it did. – JeremyP Aug 22 '12 at 14:54
  • +1 great stuff (and sorry about the confusion on my part)! – Dan Rosenstark Aug 22 '12 at 14:56
3

It is purely a style issue.

I don't know which examples use the underscored ivar style. The official Apple examples (e.g. CryptoExercise) do not prefix the ivars with _.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 1
    Apple uses it for its own code – Philippe Leybaert Aug 19 '10 at 11:34
  • 1
    @Phil: Never seen those. But if they really exist that means there is no standard on naming of ivars regarding the leading `_`. – kennytm Aug 19 '10 at 13:26
  • Google's Obj-C style guide takes a similar approach, recommending a trailing underscore for ivars - http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml#Variable_Names – Kirk Kelsey Aug 19 '10 at 17:33
  • 2
    Check any of the UI*.h files for UIKit. They ALL use underscore prefixes for private ivars. – Philippe Leybaert Aug 19 '10 at 22:25
  • 2
    @Philippe: The ivar in those the classes are **not supposed to used**. Heck, Apple even uses private API internally. The point is the examples given to third-party developers never use the leading `_`. – kennytm Aug 20 '10 at 06:22
  • @KennyTM: of course they're not supposed to be used. They're private. My point is that Apple uses this naming convention for internal code, although they tell us to do it differently. – Philippe Leybaert Aug 20 '10 at 07:03
2

I will just point out that a new navigation project using core data uses trailing underscores by default and makes the variables private.

@interface MyTestAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;
    UINavigationController *navigationController;

@private
    NSManagedObjectContext *managedObjectContext_;
    NSManagedObjectModel *managedObjectModel_;
    NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}

@interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {

@private
    NSFetchedResultsController *fetchedResultsController_;
    NSManagedObjectContext *managedObjectContext_;
}
jon
  • 92
  • 3
  • 11
1

The KVC part of the runtime expects either a name or _name ivar when using valueForKey: on an object when it cant find a message to retrieve that variable. see http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html

If the runtime bothers to search for _name and the apple documentation mentions the _name first there might be a good reason for this. Let's take a look at some SDK classes: UINavigationBar.h this class has underscores in front of all ivars, UIView too... the list goes on. Well maybe it is that way with the new fangled iOS SDK and good ole NS* classes don't do thinges that way... wrong; they use the underscore as well in the header files.

Apple uses the underscore in private API messages as well as ivars. I can't understand why their examples do not push this behavior especially when the runtime bothers to have this so called "naming convention" hard coded into the variable search path. It would be nice to see some consistency.

Just a note, there is a strict naming scheme you have to follow to be KVC compliant; the link above helps you to conform to this to use this handy feature of the runtime.

Brent Priddy
  • 3,817
  • 1
  • 24
  • 16