views:

96

answers:

3

The following doesn't complain at compilation nor runtime about no name ivar. So why is it so common to see an ivar and @property/@synthesize.

@interface PropTest : NSObject
{
}
@property (retain) NSString *name;
@end

@implementation PropTest
@synthesize name;
@end

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  PropTest *p = [[PropTest new] autorelease];
  p.name = @"Hello, World!";
  NSLog(@"%@",p.name);
  [pool drain];
  return 0;
}

This code prints

Hello, World!

In fact, if i access p->name, i get a warning:

warning: instance variable 'name' is @private; this will be a hard error in the future

which indicates that an ivar is created for me if one doesn't exist.

If that's true, what's the point of creating the ivar manually (ignoring the obvious, that there are sometimes valid reasons for not using the g/setter accessor)?

Or asked differently, should i only ever create an ivar for a property when i need to bypass the accessors?

Thanks

+5  A: 

Synthesized ivars (the ability to not manually declare ivars) is a feature of the new Objective-C runtime, which still isn't being used on all systems. For 32-bit Macs (and, until recently, the iPhone simulator), you have to manually declare ivars. If you're only targeting systems with the new runtime, there's no reason to manually declare ivars.

eman
+2  A: 

eman's answer is correct overall, but there is one reason to still declare ivars even in the new runtime: Apple discourages synthesized accessors in init and dealloc methods. Essentially, getters and setters are allowed to have side-effects other than just setting a variable. In particular, they could trigger KVO notifications. With an ivar to talk to, you can just send release and be done with it. But if all you have is a property, your only choice is to set it and hope you avoid any unfortunate interactions.

I'm not sure how big a problem this is in practice, to be honest. I've just superstitiously avoided it, even though I secretly doubt it would cause a problem in most cases. But Apple does make a point of this in the docs, so I assume there is some reason to be concerned.

Chuck
You can still access the ivar directly with synthesized ivars (there was a bug where you couldn't but I'm pretty sure it's fixed now), so this isn't a problem.
eman
@eman: IIRC they're planning a fix, but it's not in unless you're using prerelease Xcode builds.
Chuck
@Chuck Direct access of synthesized ivars works as of 3.2.4.
Preston
A: 

Two not-so-good-but-necessary reasons to make sure properties are backed up by ivars:

  1. For some reason the XCode debugger doesn't show properties that don't have corresponding ivars explicitly declared.
  2. It seems to me that under some circumstances using @property without an ivar can hide other ivars, resulting in compilation errors (see http://stackoverflow.com/questions/3957288/why-does-a-subclass-property-with-no-corresponding-ivar-hide-superclass-ivars )

Unless I've got the wrong ends of a couple of sticks here, I think the use of @property without explicit ivars may lead to annoyances not warranted by the convenience.

Cris