-1

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

In the interface you have foo_ and then the property foo. In implementation you then have @synthesize foo = foo_. What's the difference here between foo and foo_.

Community
  • 1
  • 1
Eric Brotto
  • 53,471
  • 32
  • 129
  • 174

4 Answers4

1
@synthesize foo = foo_

makes the compiler generate an error if you use only foo

this is done so that you don't mistakingly mess with its retain count...

so it is far less likely you will do _foo = something ;

than

 foo = something; .

Apple wants you to use proper setter methods.. i.e. self.foo = something

Shubhank
  • 21,721
  • 8
  • 65
  • 83
1
@property SomeType *foo;

...

@synthesize foo = _foo;

Creates the @property foo, but its value is stored in an ivar named _foo, not foo.

That is, you would access the @property like this:

yourObject.foo = someValue;

But in your class implementation, you would access the ivar directly with _foo, not foo. As Shubhank says, this makes it harder to accidentally access the ivar _foo when you instead want to use the @property foo instead.

If you had @synthesize foo; instead, then both the @property and the ivar would be named foo.

Now, if you explicitly declared SomeType *_foo to be used to for the @property—like in the case Novarg mentions—then you'd need to do @synthesize foo = _foo to get the compiler to use the existing ivar _foo instead of creating a new one named foo. However, even if you didn't do so, just using the two lines of code above will make the compiler automatically declare the ivar SomeType *foo.

yuji
  • 16,695
  • 4
  • 63
  • 64
0

The @synthesize directive tells the compiler to create an instance variable for your declared property.

for example, if you declare in your .h file:

@property (nonatomic, retain) NSString *foo;

and in your .m file

@synthesize foo;

This will generate a private instance variable NSString *foo, as well as accessor methods:

- (void)setFoo:(NSString *)foo;
- (NSString *)foo;

Code within the class may look like

self.foo = @"bar";    // set through accessor - dot notation
[self setFoo:@"bar"]; // set through accessor - method notation

foo = @"bar";         // direct assignment

If you are not using ARC, the second example would be unsafe, as you're assigning an autoreleased string instead of a retained string. This would be released and you're left with a dangling pointer, which would crash when accessed. What you probably meant to do was to use the accessor, or to retain the object on assignment e.g. foo = [@"bar" retain];

By declaring a different variable in your .m file:

@synthesize foo = _foo;

What you're doing is telling the compiler to create the private instance variable NSString *_foo instead.

I prefer to do it this way, as the underscore makes it more clear in your implementation when you are accessing the instance variable directly vs. through an accessor method. Especially when using dot notation. As in the example above, the code would look like:

_foo = @"bar";     // direct assignment

You can instantly see that you're assigning to an ivar directly, and should be aware of the memory semantics involved.

Ryan
  • 5,416
  • 1
  • 39
  • 36
0

The declaration:

@interface MyClass
{
   MyOtherClass *foo_;
   ...
}
...

declares an instance variable foo_. The declaration:

@interface MyClass

@property (retain) MyOtherClass *foo;
...

declares a property foo. Now a property is just shorthand for declaring two methods - a setter (- (void) setFoo:(MyOtherClass *)obj) and a getter (- (MyOtherClass *) foo). A property is usually (not always) backed by an instance variable, and if you have the compiler write the setter & getter for you by using @synthesize then the backing variable (pre XCode 4.4) has the same name as the property. The statement:

@synthesize foo = foo_;

instructs the compiler to write the setter & getter but to use the variable foo_ as the backing variable.

So the difference is that foo is the name of a property and used either in dot notation (myClassInstance.foo) or, less usually, by directly calling the setter or getter (e.g. [myClassInstance foo]); while foo_ is the name of an instance variable and accessed using arrow notation (e.g. self->foo_ within the class, or myClassInstance->foo_ outside the class if accessible, the former can drop the self->).

If you've written you own custom setter/getter, or if you are using manual memory management and synthesized retain or copy properties the difference is huge as foo_ by passes the setter/getter and hence the custom code or the synthesized memory management code.

Under ARC or GC and synthesized retain/strong/weak/copy properties the difference is less significant - in either case the memory management will be handled automatically.

CRD
  • 52,522
  • 5
  • 70
  • 86