Objective-c – Correct way to alloc/init instance variables in Objective-C

iphoneobjective c

I was looking at some sample code on Jeff LaMarche's excellent blog when I came across the following:

- (void)applicationDidFinishLaunching:(UIApplication*)application
{
    CGRect rect = [[UIScreen mainScreen] bounds];

    window = [[UIWindow alloc] initWithFrame:rect];

    GLViewController *theController = [[GLViewController alloc] init];
    self.controller = theController;
    [theController release];

    // ...
}

In the .h, we see that "window" and "controller" are ivars declared as so:

@interface OpenGLTestAppDelegate : NSObject 
{
    UIWindow            *window;
    GLViewController    *controller;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet GLViewController *controller;
@end

My question is: Why are "window" and "controller" assigned in different ways?

I think I understand why each kind of assignment works (keeping track of retain count), but why are they assigned in different ways? Specifically, why isn't controller assigned in the same way window is with a single line like so without going through the setter:

    controller = [[GLViewController alloc] init];

In general, when would you use the single line method and when would you use the multiple line method?

Thanks.

Best Answer

Does he create a custom setter for the controller instance variable?

If so, there may be code which is called when the controller variable is changed through the setter. Merely setting the controller variable with:

controller = [[GLViewController alloc] init];

would not invoke the setter method; however, assigning the newly allocated object to a local variable then setting it with:

self.controller = theController;

would invoke the setter method since it is a shorthand way of writing:

[self setController:theController];

and the extra code in the setter would be executed. This is commonly where you would expect the differentiation between the two methods.

Edit:

Evidently, after taking a look at the code, he doesn't implement a custom setter method, however the method that he has used is still most commonly used when a custom setter method would be implemented.

My guess at the reason behind the extra code would be that he plans to release the variable after allocation, and if assigned to a local variable, he can call the setter method with the local variable and then call release on the local variable afterwards. This would be overall more readable than using

[[self controller] release]

However, it is an odd way to do it, as the synthesized implementation of the setter will retain the instance variable, yet he then releases it once it has been set to the instance variable, and as the release call cancels out the retain call, it would make more sense to set the variable using the one-line method.

Related Topic