Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of UIViewController initialization and loading

People also ask

What comes first viewDidLoad or viewWillAppear?

viewWillAppear(_:)Always called after viewDidLoad (for obvious reasons, if you think about it), and just before the view appears on the screen to the user, viewWillAppear is called.

Which method is called first in viewController?

The view controller calls its loadView method.

What is UIViewController life cycle?

The LifecycleThe view controller lifecycle can be divided into two big phases: the view loading and the view lifecycle. The view controller creates its view the first time the view is accessed, loading it with all the data it requires. This process is the view loading.

Is loadView called before viewDidLoad?

Use viewDidLoad( ), which is called AFTER loadView( ) has completed its job and the UIView is ready to be displayed. viewDidLoad( ) allows you to initialize properties of the view/viewController object and finalize them before viewWillAppear( ) is called.


The view loading system on the iPhone works like this:

When you initialize a view controller (either with -init or -initWithNibName:bundle:), it doesn't actually create and initialize the view. When you call -view for the first time, it calls -loadView. By default, -loadView just loads the view from the xib file (nibName). If you override this, though, you're responsible for creating the view and assigning it to the view controller's view property. As an example:

- (void)loadView
{
   UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
   // add subviews 
   self.view = view;
   [view release];
}

Every time you create the view, which is different from the view becoming visible and showing onscreen, it calls -viewDidLoad. (-viewDidAppear/-viewDidDisappear is for the visibility of the view on-screen)

Since we're already off-track, let's consider memory management. When the view is offscreen, the system will automatically set the view property of a view controller to nil. The problem is that all the subviews of that view are leaking. How so? Well, the retain count for each subview is 2 (views retain subviews, and your view controller has an outlet/ivar to it). When the view is nil, the retain count of that view is 1. It doesn't make sense for a view to stick around if a view isn't showing, so you set it to nil in -viewDidUnload (which is a hook for whenever the view is set to nil).


The initWithNibName:bundle: method is the designated initializer for the UIViewController class.

Try overriding and using it instead of init:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    }
    return self;
}

...

UIViewControllerSubClass *someViewController = [[UIViewControllerSubclass alloc] initWithNibName:@"UIViewControllerSubclass" bundle:nil];

-(void)awakeFromNib
{
}

is only called if you are using story board to store the ViewController drawn in story board Nib---means interface bundle.

the proper sequence is

-(void)initWithCoder
-(void)awakefromNib    //(if story board is used)
    or
-(void)loadView----() //if manually generating the view contoller

-(void)viewDidLoad-----(called only once in the life cycle of viewController)
-(void)viewWillAppear
-(void)viewDidAppear

While moving to a new ViewController

-(void)viewWillDisappear
-(void)viewDidDisappear

While returning to the first ViewController

-(void)viewWillAppear
-(void)viewDidAppear

gerry3 is right. This stuff still confuses me too. Check out the docs on designated initializers.

Also note that if your controller is created by a nib being loaded then only initWithCoder will get called. loadView doesn't get called in that case either.

Because of this it seems like most of the code I've seen does most initialization in stuff like viewDidLoad even though that seems wrong, but it seems to be the best method that gets called in both cases where something is loaded in a nib and created programmatically.

But the reason this seems out of order is that the [super init] is calling loadView etc. –