views:

3549

answers:

7

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];//?????????
}
A: 

Related: Understanding reference counting with Cocoa / Objective C

Sören Kuklau
@Soeren: I have already read that article, and understand it's contents. My question was in relation to objects instantiated on an IB xib, which it doesn't cover.Eg: I never actually create or allocate the label, the IB magic does all that. So what I need to know is simple:do I need to release it?
rustyshelf
A: 

You do alloc the label, in a sense, by creating it in IB.

What IB does, is look at your IBOutlets and how they are defined. If you have a class variable that IB is to assign a reference to some object, IB will send a retain message to that object for you.

If you are using properties, IB will make use of the property you have to set the value and not explicitly retain the value. Thus you would normally mark IBOutlet properties as retain:

@property (nonatomic, retain) UILabel *lblExample;

Thus in ether case (using properties or not) you should call release in your dealloc.

Kendall Helmstetter Gelner
This is not correct. If you do not use properties (or implement your own accessor methods), then whether or not you should release depends on what platform you're on and what is your superclass. If you inherit from NSWindowController, for example, you do not release.
mmalc
+4  A: 

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

rustyshelf
A: 

Any IBOutlet that is a subview of your Nib's main view does not need to be released, because they will be sent the autorelease message upon object creation. The only IBOutlet's you need to release in your dealloc are top level objects like controllers or other NSObject's. This is all mentioned in the Apple doc linked to above.

Eric Allam
This is actually wrong. Whether or not you should send top-level objects a release message depends on what platform you're using and from what class your File's Owner inherits. For example, if it inherits from NSWindowController, you do not need to release them.
mmalc
+21  A: 

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.

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];
}
mmalc
+2  A: 

The

[anOutlet release], anOutlet = nil;

Part is completely superfluous if you've written setView: correctly.

Wil Shipley
A: 

If you don’t release it on dealloc it will raise the memory footprint.

See more detail here with instrument ObjectAlloc graph

Shaikh Sonny Aman