Question

I am trying to understand the purpose of the synthesize directive with property name overriding. Say that I have an interface defined as follow:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

And in the implementation file, I have:

@synthesize dummyLabel = _dummyLabel;

From what i understand, "dummyLabel" is just an alias of the instance variable "_dummyLabel". Is there any difference between self._dummyLabel and self.dummyLabel?

Was it helpful?

Solution

Yes. self._dummyLabel is undefined, however _dummyLabel is not.

Dot syntax expands out to simple method invocations, so it's not specific to properties. If you have a method called -(id)someObject, for example in the case of object.someObject, it will be as if you wrote [object someObject];.

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work

OTHER TIPS

Your understanding is incorrect. dummyLabel is the name of the property, and is not an alias for the instance variable - the instance variable is only called _dummyLabel. So the following holds for an instance of Dummy called myObject:

  • [myObject dummyLabel] works
  • myObject.dummyLabel works
  • [myObject _dummyLabel] fails
  • myObject._dummyLabel fails
  • myObject->dummyLabel fails
  • myObject->_dummyLabel depends on the visibility of the ivar (@public, @private, @protected)
  • [myObject valueForKey: @"dummyLabel"] works
  • [myObject valueForKey: @"_dummyLabel"] depends on the implementation of +accessInstanceVariablesDirectly (i.e. it will work in the default case where +accessInstanceVariablesDirectly returns YES).

The advantage of having another name for the ivar than for the property is that you can easily see in the code when you are accessing one or the other - Andre K

I'm not able to find a 'comment' button so I'm having to post as an 'answer'.

Just wanted to expand on Andre's comment - by knowing when you are using the synthesized properties vs the vanilla variable, you know (especially in case of setters) when a variable is being retained/copied/released automatically thanks to your nice setter, vs being manipulated by hand.

Of course if you are doing things right, you probably don't need the help of a setter to retain/release objects properly! But there can be other scenarios too where referring to your ivars as self.ivar instead of _ivar can be helpful, such as when you are using custom setters/getters instead of the default synthesized ones. Perhaps every time you modify a property, you also want to store it to NSUserDefaults. So you might have some code like this:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

Note: This is just illustrative code, there could be a thousand things wrong with it!

So now, in your code, if you have a line that says _autoLoginOn = YES - you know it's not going to be saved to NSUserDefaults, whereas if you use self.autoLoginOn = YES you know exactly what's going to happen.

The difference between _autoLoginOn and self.autoLoginOn is more than just semantic.

I don't see any big advantage of renaming _dummyLabel to dummyLabel

In some ObjC runtimes you have a hard time making instance variables invisible to users of the class. For them sticking some prefix (or suffix) on your instance variables can make it clear (or more clear) that you don't want anyone messing with your variables. However you don't want that gunk on your public functions. This lets you get it off.

It could also be useful if you need to maintain an old interface with one set of names at the same time as a new set of APIs with a new set of names (setLastname vs. setSurname).

Old post, but I think its important to mention, that it is recommended to access variables via getters and setters (so, with dot notation). Accessing a field directly (_ivar) is strongly recommended only when initializing it.

There is some good Apple's article: https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

Last paragraph:

You should always access the instance variables directly from within an initialization method because at the time a property is set, the rest of the object may not yet be completely initialized. Even if you don’t provide custom accessor methods or know of any side effects from within your own class, a future subclass may very well override the behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top