Property vs instance variable in Objective-C [duplicate]

Solution 1:

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?

Solution 2:

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.

Solution 3:

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 

Solution 4:

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.

Solution 5:

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 _.