@synthesize window


#1

So in the latest XCode, it uses this line:

This threw me off for a while, I couldn’t figure out why I had a blank screen when running the program. I finally downloaded the example code and caught the difference. Your code uses:

Can you tell me why the new XCode might use the _window assignment?


#2

Do you want my personal opinion or the facts? I’ll save the opinion for the end. :slight_smile:

When you synthesize a property, you are really assigning the instance variable that gets accessed by the two methods (getter/setter) declared by the property. The compiler does the following to figure out what you mean:

  1. Is there an instance variable with the same name as the property? If so, the two property accessor methods will set and return that instance variable.
  2. Is there no instance variable with the same name as the property? If so, automatically add an instance variable to this class with the same name as the property.
    * Within your implementation, you can access this instance variable directly. Therefore, this is all valid:
@interface Foo : NSObject 
{
}
@property (nonatomic, retain) NSObject *bar;
@end
@implementation Foo
@synthesize bar; // This creates an instance variable: NSObject *bar;
- (void)dealloc {
    [bar release]; // We can access this ivar directly
    [super dealloc];
}

Now, if you assign an ivar to a property in the synthesize statement, you are choosing which instance variable which this property accesses.

@synthesize bar = myBar;
  1. If the assigned instance variable exists, then that property will access that instance variable; similar to item 1.
  2. If the assigned instance variable does not exist, then it will automatically be created; similar to item 2.
@interface Foo : NSObject
{
}
@property (nonatomic, retain) NSObject *bar;
@end
@implementation Foo
@synthesize bar = myBar; // This creates instance variable named myBar
- (void)method
{
     [[self bar] doSomething]; // We access myBar thru the property bar
}
- (void)dealloc
{
     [myBar release]; // We can still access myBar directly, but not "bar", because "bar" as an ivar doesn't exist
     [super dealloc];
}
@end

Now, the ability to create instance variables like this is awesome. Previously, we had to declare an ivar AND a property. That was way too much typing.

However, the way they have it set up in this template is stupid. Declaring the window as a property means other objects can access it. First of all, you can get the window object in a number of different ways (-[UIView window], -[UIApplication keyWindow], etc.), there is no reason to go through the application delegate to get the window. Besides, when do you ever need the window object, anyway?

The other problem is that Apple really reserves the _ivar naming convention for its own classes, so when you subclass those classes, you are free to name instance variables whatever you want as long as they don’t have a leading underscore. Introducing the underscore in our classes as a “valid” way of doing things will likely lead to a problem in the future, when people start saying, “Well, Apple uses an underscore, so will I,” and you start getting namespace collisions.

If I were writing the template (that is, if it were a good template), it would just be:

@interface MyAppDelegate : NSObject <UIApplicationDelegate>
{
    IBOutlet UIWindow *window;
}

@end

#3

I got bit by this one too - spent almost a day on it! Luckily I saw this post. Thanks for sharing.