Properties for IBOutlets missing in procedure


On page 75, the MapKit Framework section describes adding the IBOutlets as instance variables. Why don’t these (and locationManager, for that matter) need to be added as [color=#0040BF]@properties[/color], and then synthesized in the .m file? Do we not need accessors to these variables?


Correct, these objects do not need accessors.

A class exposes to other objects its instance variables thru accessors (properties are a shortcut for creating those accessors). If a class does not wish for other objects to access its instances’ variables, it should not create properties for them. In effect, instance variables that do not have accessors are “private”. Only the object that owns them can play with them. An object can always get at its own instance variables within an instance method by directly accessing the instance variable. Accessing an ivar directly is simply a memory offset, whereas accessing an ivar via an accessor involves sending a message and invoking the corresponding method.

@interface Foo : NSObject
    id myIvar;
- (void)myMethod;
- (void)myMethod
    NSString *name = [myIvar name]; // <-- Direct access, no need to use an accessor to do a [[self myIvar] name];

This is the case for WhereamiAppDelegate; within the implementation of WhereamiAppDelegate. We don’t want other objects messing with the location manager or the map view, so, they are not exposed through a property. Besides, only one object (UIApplication) has a pointer to the instance of WhereamiAppDelegate. Therefore, no object will ever send a message to the WhereamiAppDelegate instance asking for/setting its map view or location manager.

As far as where to put the IBOutlet tag, Interface Builder doesn’t care. It uses a relatively simple parsing mechanism to decide if it should allow these pointers to be connected (“I see IBOutlet, I will look at the next two words for the type and the name of that outlet.”). Apple has adopted putting the IBOutlet tag on the property if there is a property. I tend to disagree with this approach: I like to have all of my IBOutlets in the same place for readability, and because not all instance variables will have property accessors, I put my IBOutlets on the instance variable declaration. Either way is fine, but of course, I’d be slightly happier if everyone chose my style. :slight_smile:

The confusing bit is the template: the window is always as exposed as a property. In my opinion, this is silly. There shouldn’t be a need to ask the application delegate for the window of the application. In fact, as you progress later in the book and start to write more meaningful applications with view controllers, the application delegate is little more than an object that responds to application events - as it should be. (There is a few paragraphs about this design decision later on in the book.) If you need to get at the window somewhere else in your application (a rarity), there are methods in UIApplication and UIView for grabbing a pointer to it.