Alex Rivera | Logout

iOS - What is best way to manage memory for IBOutlets?

Asked 2011-03-08T13:15:40.447
10

I've been reviewing the Apple docs and sample code to try to determine the best way to manage memory for IBOutlets. I'm a little confused, to say the least.

The CurrentAddress sample code declares IBOutlets as properties:

@interface MapViewController : UIViewController <MKMapViewDelegate, MKReverseGeocoderDelegate>

{
    MKMapView *mapView;
    UIBarButtonItem *getAddressButton;
}
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *getAddressButton;

Great. And these are released in dealloc:

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

Now shouldn't these properties be set to assign? Because when set to retain, the IBOutlet's retain count will be increased twice: once when the nib is loaded and another time when the property is set? And wouldn't it be better to set these properties to nil instead of releasing in dealloc?

Edit
Report

1 Answer

0

I'm assuming you @synthesize these properties. If you didn't, you would need to release yourself manually. You are very correct in your assumption that if you continued to retain when a property is set, you would leak memory.

Let's think.... what did properties used to look like before we had the fancy @synthesize statement?

id _propertyName; // the ivar

- (id) propertyName {
  return _propertyName;
}

- (void) setPropertyName:(id)v {
  if (_propertyName) {
    [_propertyName release]; // release the previously retained property
  }
  _propertyName = [v retain]; // retain this one so it doesn't fly away on us
}

Now, you don't need to type this stuff, because @synthesize is cool and generates that for you, it will also generate @synchronized blocks if you do not specify something as being nonatomic, which is also pretty rad.

If you specified assign instead of retain, you'd get something like this

id _propertyName; // the ivar

- (id) propertyName {
  return _propertyName;
}

- (void) setPropertyName:(id)v {
  _propertyName = v;
}

This is about the only thing you CAN do when things are not objects, because they are only values (also sometimes referred to as value types, objects are reference types). Since value types cannot be retained, the other type of block wouldn't make any sense. Go ahead and try to create a retain property with BOOL and watch what LLVM or GCC tell you to go do with what ;)

answered 2011-03-08T13:40:40.497

Your Answer