iPhone dev - viewDidUnload subviews

Posted by Mk12 on Stack Overflow See other posts from Stack Overflow or by Mk12
Published on 2010-06-02T15:05:05Z Indexed on 2010/06/02 15:24 UTC
Read the original article Hit count: 362

I'm having a hard time undestand a couple of the methods in UIViewController, but first I'll say what I think they are meant for (ignoring interface builder because I'm not using it):

-init: initialize non view-related stuff that won't need to be released in low memory situations (i.e. not objects or objects that can't be recreated easily).
-loadView: create the view set the [self view] property.
-viewDidLoad: Create all the other view elements
-viewDidUnload: Release objects created in -viewDidLoad.
didReceiveMemoryWarning: Low-memory situation, release unnecessary things such as cached data, if this view doesn't have a superview then the [super didReceiveMemoryWarning] will go on to release (unload) the view and call -viewDidUnload.
-dealloc: release everything
-viewWillAppear:, -viewDidAppear:, -viewWillDisappear:, -viewDidDisappear: self-explanatory, not necessary unless you want to respond (do something) to those events.

I'm not sure about a couple of things. First, the Apple docs say that when -viewDidUnload is called, the view has already been released and set to nil.

  1. Will -loadView get called again to recreate the view later on?
  2. There's a few things I created in -viewDidLoad that I didn't make a ivar/property for because there is no need and it will be retained by the view (because they are subviews of it). So when the view is released, it will release those too, right? When the view is released, will it release all its subviews? Because all the objects I created in -viewDidLoad are subviews of [self view]. So if they already get released why release them again in -viewDidUnload? I can understand data that is necessary when the view is visible being loaded and unloaded in these methods, but like I asked, why release the subviews if they already get released?

EDIT: After reading other questions, I think I might have got it (my 2nd question). In the situation where I just use a local variable, alloc it, make it a subview and release, it will have a retain count of 1 (from adding it as a subview), so when the view is released it is too. Now for the view elements with ivars pointing to them, I wasn't using properties because no outside class would need to access them. But now I think that that's wrong, because in this situation:

// MyViewController.h
@interface MyViewController : UIViewController {
    UILabel *myLabel;
}

// MyViewController.m
. . .
- (void)viewDidLoad {
    myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 10)];
    [myLabel setText:@"Foobar"];
    [[self view] addSubview:myLabel];
}

- (void)viewDidUnload [
    // equivalent of [self setMyLabel:nil]; without properties
    [myLabel release];
    myLabel = nil;
}

In that situation, the label will be sent the -release message after it was deallocated because the ivar didn't retain it (because it wasn't a property). But with a property the retain count would be two: the view retaining it and the property. So then in -viewDidUnload it will get deallocated. So its best to just always use properties for these things, am I right? Or not?

EDIT: I read somewhere that -viewDidLoad and -viewDidUnload are only for use with Interface Builder, that if you are doing everything programmatically you shouldn't use them. Is that right? Why?

© Stack Overflow or respective owner

Related posts about iphone

Related posts about objective-c