Search code examples
objective-cxcodepropertiesoutlet

Xcode 4.5 Interface Builder Adds Underscores to Outlets


Does Xcode 4.5 have a slightly different manner of auto-generating properties and their associated memory release sections (in dealloc and viewDidUnload)?

I upgraded to Xcode 4.5 from 4.5 Beta 1 yesterday. Now when I use Interface Builder to create an outlet (by Ctrl-dragging from, say, a UILabel to the associated header file), it creates the @property declaration in the header as normal:

@property (retain, nonatomic) IBOutlet UILabel *propertyName;

However, in the associated .m file, there is no @synthesize declaration.

The code in viewDidUnload is normal:

- (void)viewDidUnload {
    [self setPropertyName:nil];
    [super viewDidUnload];
}

However, the code in dealloc prepends an _ on the property name:

- (void)dealloc {
    [_propertyName release];
    [super dealloc];
}

This also means I cannot reference the property as normal ([propertyName doSomething];)

Did something change? Or did I accidentally coincidentally change some setting?


Solution

  • Yes, the behavior has changed slightly in Xcode 4.5.

    ... in the associated .m file, there is no @synthesize declaration.

    In Xcode 4.5, the @synthesize statement is now optional, and properties are synthesized automatically. Automatically generated IBOutlet properties therefore no longer add @synthesize because it's no longer required.

    ... the code in dealloc prepends an _ on the property name

    When properties are synthesized automatically (without an explicit @synthesize statement) the corresponding instance variable is prepended with an underscore. That's why it shows up as such in your dealloc method. This is so the instance variable and property names don't overlap.

    This also means I cannot reference the property as normal

    No. Accessing instance variables and properties has not changed. All that has changed is the default name of the instance variable. E.g.:

    _foo = @"Bar"; // Setting an instance variable directly.
    self.foo = @"Bar";  // Setting an instance variable via a property accessor method.
    

    The underscore is merely a matter of style, so that it's more clear that you're accessing the instance variable rather than the property.

    Note that you can add a @synthesize statement yourself, and that will force the name of the corresponding instance variable to be whatever you want it to be. Likewise, if you add your own property accessor methods then that will prevent the instance variable from being generated automatically.