1

Possible Duplicate:
Synthesized property and variable with underscore prefix: what does this mean?

The usage of Objective-C properties has always felt awkward to me. It's one of the "I know how to use them, but I'm not always sure why I'm using them." kind of things and recently I've been seeing a lot of this:

// in .h file
@interface MyObject : NSObject
{
     id _coolIvar;
}
@property (assign) id coolIvar;
@end

// in .m file
@implementation
@synthesize coolIvar = _coolIvar;// <- whats the point of that.
@end

So what is the point of declaring an ivar with an underscore and then using @synthesize to access it, Opposed to just declaring the @property with the same name as the ivar?

Side Question: I've noticed that this convention has been becoming increasingly more popular since blocks started becoming the preferred approach for async callbacks opposed to the target/selector approach. Is that a coincidence or does the above @property declaration convention play nicer with block scopes?

Community
  • 1
  • 1
Eric L
  • 640
  • 6
  • 20

5 Answers5

3

I use the _ivar construct to make sure that I don't access the ivar directly (by mistake) when I really intend to go through the accessors.

Monolo
  • 18,205
  • 17
  • 69
  • 103
3

It's preference.

It's also my preference to not declare the variables twice and just let them be synthesized like:

// in .h file
@interface MyObject : NSObject
@property (assign) id coolIvar;
@end

// in .m file
@implementation
@synthesize coolIvar = _coolIvar;
@end

The two reasons I like to use the _ prefix is

  1. I know when I am going through an accessor and when I am accessing the variable straight.
  2. If it makes sense for me to call an ivar address it is more than likely that inside a method a similar variable would also be logically called address. If my ivar does not have an _ prefix then my local address will mask the ivar address.

I also like how xcode will autocomplete vaiables starting with an _ when you start typing your @synthesize myVar = _...

NB
You may run into the odd name clash (I have only once) but the warning that the complier gives you makes it a pretty easy spot and simply changing the name is a quick win.

@isaac touched on not declaring ivars so that they are not publicly advertised but does not explain how/why. Basically you can declare @property's in a class extension to still give you the benefits of the @synthesized getter/setter but without making your public API look ugly.

Your previous example would look like this (if you wanted coolIvar to not be publicaly advertised):

// in .h file
@interface MyObject : NSObject
@end

// in .m file
@interface MyObject () <-- Like a category but with no name
@property (assign) id coolIvar;
@end

@implementation
@synthesize coolIvar = _coolIvar;
@end
Paul.s
  • 38,494
  • 5
  • 70
  • 88
  • Oh, wow cool. I had no idea you could implicitly declare ivars like that. Time to go un-verbose some code haha. Thanks. – Eric L Nov 30 '11 at 23:48
3

With the modern runtime (iPhone applications and 64-bit programs on Mac OS X v10.5 and later) the ivar declaration is no longer required. So your code is reduced to:

// in .h file
@interface MyObject : NSObject

@property (assign) id coolIvar;

@end

// in .m file
@implementation

@synthesize coolIvar = _coolIvar;

@end

Per @Monolo's answer, the _ivar is a good failsafe to make sure you don't inadvertently access the ivar directly. Remember, the @property and @synthesize is there to replace boilerplate code - without it you'd have to code getter and setter accessors.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
1

There are a couple benefits to differentiating ivars from property accessors.

One is described by Monolo - it prevents mistakingly accessing an ivar when what you intended to access was a property.

Another is that in theory it guards against collisions - cases where you might name an ivar identically to another ivar that's beyond your implementation (ie, a superclass ivar name).

There are different thoughts on best practices, but lately I've read in several places I consider reliable that the best practice is actually to no longer to declare ivars at all in your interfaces (ivars are created implicitly via the property declaration).

Some people don't like "implicit" - but there are material benefits: Not declaring them avoids advertising ivars that aren't really public. It also goes even further in avoiding collisions - because in theory when a property is synthesized and the ivar generated, it will do so without introducing a convention that may itself collide with a private ivar naming convention (as may be the case with preceding or trailing underscore).

isaac
  • 4,867
  • 1
  • 21
  • 31
0

Preference. Some people like to prefix instance variables with a underscore (so one can easily tell if one is referencing a ivar, or a variable in a more local scope), and some don't.

mipadi
  • 398,885
  • 90
  • 523
  • 479