Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to release xib resources?

If I have something like a UILabel linked to a xib file, do I need to release it on dealloc of my view? The reason I ask is because I don't alloc it, which makes me think I don't need to release it either? eg (in the header):

IBOutlet UILabel *lblExample;

in the implementation:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}
like image 250
rustyshelf Avatar asked Sep 15 '08 03:09

rustyshelf


2 Answers

If you follow what is now considered to be best practice, you should release outlet properties, because you should have retained them in the set accessor:

@interface MyController : MySuperclass {
    Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end


@implementation MyController

@synthesize uiElement;

- (void)dealloc {
    [uiElement release];
    [super dealloc];
}
@end

The advantage of this approach is that it makes the memory management semantics explicit and clear, and it works consistently across all platforms for all nib files.

Note: The following comments apply only to iOS prior to 3.0. With 3.0 and later, you should instead simply nil out property values in viewDidUnload.

One consideration here, though, is when your controller might dispose of its user interface and reload it dynamically on demand (for example, if you have a view controller that loads a view from a nib file, but on request -- say under memory pressure -- releases it, with the expectation that it can be reloaded if the view is needed again). In this situation, you want to make sure that when the main view is disposed of you also relinquish ownership of any other outlets so that they too can be deallocated. For UIViewController, you can deal with this issue by overriding setView: as follows:

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}

Unfortunately this gives rise to a further issue. Because UIViewController currently implements its dealloc method using the setView: accessor method (rather than simply releasing the variable directly), self.anOutlet = nil will be called in dealloc as well as in response to a memory warning... This will lead to a crash in dealloc.

The remedy is to ensure that outlet variables are also set to nil in dealloc:

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}
like image 149
mmalc Avatar answered Oct 20 '22 13:10

mmalc


I found what I was looking for in the Apple docs. In short you can set up your objects as properties that you release and retain (or just @property, @synthesize), but you don't have to for things like UILabels:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

like image 4
rustyshelf Avatar answered Oct 20 '22 13:10

rustyshelf