Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is @synthesize foo = _foo all about?

Why does one want this underscore prefix in an iOS app?

like image 788
Surfer Avatar asked Sep 01 '11 20:09

Surfer


2 Answers

Sometimes it helps to see whats happening behind the scenes to understand. Basically when you see this

@property (nonatomic, retain) Foo *foo;

With this in the implementation

@synthesize foo=_foo;

It's syntax sugar for the following, meaning that the compiler basically generates this code for you

Foo *foo = nil;

-(Foo *) foo {
    return _foo;
}

-(void) setFoo:(Foo *)val {
    if( _foo != val ) {
        [_foo release];
        _foo = [val retain];
    }
}

This way when you refer to the public property, you hit it through the generated accessories of self.foo and if you want to refer to the instance variable inside your class you can refer to _foo. Before XCode four it was easy to get confused between the two. You could do something like

self.foo = foo1;

foo = foo2;

This was perfectly legal and could cause problems on a couple levels. The second line doesn't use the accessor so foo2 would not be retained which could cause it to be picked up by garbage collection prematurely. Even worse, the second line doesn't use the accessor which would release any previous value meaning it would cause a memory leak.

So in summary, the new technique creates a getter and setter for you property and allows you to also specify the name to be used for the instance variable, used for encapsulation.

like image 172
jerrylroberts Avatar answered Oct 18 '22 12:10

jerrylroberts


Here's why I do this at times:

If I want to do lazy loading on a property I will typically underscore my ivar so that the work done to load the desired data from the back-end server/saved file/what-have-you is only loaded the first time. For example:

- (NSMutableArray *)recentHistory;
{
   if (_recentHistory == nil)
   {
       // Get it and set it, otherwise no work is needed... hooray!
   }

   return _recentHistory;
}

So here calls to the property [instanceOfClass recentHistory] (or instanceOfClass.recentHistory) will check the ivar to see if it needs to load the data or just return the already loaded data.

It is overkill to declare all of your properties this way.

Hope that helps.

like image 37
Ryan Crews Avatar answered Oct 18 '22 13:10

Ryan Crews