tags:

views:

914

answers:

5

Do you have to release IBOulets in dealloc? I'm not sure on this one because I didn't do the alloc and typically you only release for something you called alloc on. Anyone know?

+1  A: 

As you said, you should release everything that you allocated yourself (with alloc or copy). It works the other way: you should not release any Cocoa objects you did not allocate yourself (some CoreFoundation functions allocate, and you're responsible for releasing them, but it's not the case here).

If you didn't allocate your IBOutlet, then you don't have to release it, unless of course, for some reason, you retained it somewhere.

naixn
+3  A: 

It's not about IBOutlet, it's about your declaration. If you use a new project wizard in Xcode, you probably get some code like this in your header file.

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

You can see, there's retain keyword in the header file. Following the memory management guideline, you MUST release everything your retain (by calling alloc, copy, retain, etc.). And you have retain in your code then you must release it.

Additionally, the wizard already add some release code for you.

- (void)dealloc {
    [tabBarController release];
    [window release];
    [super dealloc];
}
iwat
+5  A: 

Your IBOutlets are probably @properties. If they are, and you have retain as an attribute, then you do need to release in -dealloc

In other words:

@interface MyViewController : UIViewController {
    IBOutlet UITableView *myTable;
}

@property (nonatomic, retain) IBOutlet UITableView *myTable;

@end

You will have to [myTable release]; in your dealloc.

If you make a new Navigation Based App in Xcode, and look in the appdelegate.h:

@interface Untitled1AppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;
    UINavigationController *navigationController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

and the dealloc for appdelegate.m:

- (void)dealloc {
    [navigationController release];
    [window release];
    [super dealloc];
}

The key thing to see here are lines like these:

@property (nonatomic, retain) IBOutlet UIWindow *window;

If there is a retain in there, that means that the property is being "owned" by your code and you have to release it.

Of course, there are other ways, such as not declaring the IBOutlets as properties, or declaring them as properties without retaining. I find that in most cases I prefer to have them be retained properties, which I then have to explicitly release. An example of this is when you flip from one view controller to another. As one view controller is dismissed, its views are removed and they are released. Any IBOutlet UILabels on that view would get released too if I don't have them retained. That means that when I flip back to the old view, I have to go through and reset my labels and controls to their last values, when I could have easily kept them saved if I just retain the IBOutlet.

mahboudz
+3  A: 

If you just use IBOutlet in your interface, you DO NOT need to release them. Reason being is that unless you explicitly retain them in your code, they are merely being set. They stick around because the view is there. Obviously, if you also use properties and retain them, you need to release on dealloc.

ZaBlanc
Isn't this answer conflicting with the above one? Do you need to or not? So confused.
erotsppa
No, it's not conflicting: "Obviously, if you also use properties and retain them, you need to release on dealloc".
mahboudz
As a test, make a new Nav Based App in Xcode. You will see how they release IBOutlets in their dealloc.
mahboudz
A: 

Here's what I have been doing with regard to IBOutlet objects (in conjunction with a NIB file):

@interface MyViewController : UIViewController {
  UILabel *label;
}

@property (nonatomic, retain) IBOutlet UILabel *label;

@end

@implementation MyViewController
@synthesize label;

- (void)setView:(UIView *)aView {
  if (!aView) {
    // view is being set to nil
    // set outlets to nil to get the benefit of the didReceiveMemoryWarning!
    self.label = nil;
  }
  // Invoke super's implementation last
  [super setView:aView];
}

- (void)viewDidLoad {
  [super viewDidLoad];
}

- (void)viewDidUnload {
  // Release any retained subviews of the main view.
  // e.g. self.myOutlet = nil;
  self.label = nil;
}

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc that aren't in use.
}

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

Side question: Does it make more sense to use self.label = nil in dealloc, or must release be explicitly called (for instance, to keep the static analyzer happy)?

I suppose, at that point, we're on our way out anyway, so there's no need to set our IBOutlet objects to nil.

Joe D'Andrea