PDA

View Full Version : Loading views into a controller




Labeno
Nov 17, 2008, 07:23 AM
I've noticed that as I navigate around view controllers, that the controller will occasionally reload. This reload causes crashing and other weird issues cause it recreates all the buttons, labels, etc, and reset values back to new values. Typically I use the viewWillLoad function to create all the buttons, labels, etc, and initialize class variables.

What is the proper way to load views (buttons, labels, etc) and initialize class variables into a controller just once, so there is no worry that these will be over written due to a reload later on?

Thank you for any help.



jnic
Nov 17, 2008, 08:09 AM
You should be using viewDidLoad and/or overriding the init method. Specifically, for UIViewControllers, you can override initWithNibName:

- (id)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Do your initialization here.
}
return self;
}

The init method is called when the class is constructed (so initialize your variables here). viewDidLoad is called when the view is first loaded from the nib (if you're not using a nib then use loadView), so set up your UI widgets here.

viewWillAppear is called (I believe) every time you re-display the viewController, so initializing things there will indeed cause weird behavior.

Docs: https://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:

PhoneyDeveloper
Nov 17, 2008, 10:05 AM
If your app gets a memory warning the view controllers that are not currently visible will unload their view and set it to nil. When those view controllers are shown again they will load their view and call their subclasses' viewDidLoad or loadView methods.

You need to write your code with this in mind so there are no memory leaks or other bugs if your view is unloaded.

Labeno
Nov 17, 2008, 10:43 AM
If your app gets a memory warning the view controllers that are not currently visible will unload their view and set it to nil. When those view controllers are shown again they will load their view and call their subclasses' viewDidLoad or loadView methods.

You need to write your code with this in mind so there are no memory leaks or other bugs if your view is unloaded.

This makes a lot of sense. Thank you very much for the information!!!

Can the memory warning be avoided? If so, is it a bad practice to let views remain loaded when the system is asking you to free memory?

Also, does this somehow relate to controllers taking a long time to finally show up (sometimes 4 or 5 seconds). E.g. a controller used to enter someones name using a keyboard?

PhoneyDeveloper
Nov 17, 2008, 12:00 PM
The memory warning happens if your app uses too much memory, for some definition of too much memory. If you don't free up memory the OS will kill your app.

The memory warning comes through didReceiveMemoryWarning and a similar method on your app delegate. If you don't call the base class in your derived class then I assume the base class won't release the view. However, your app could be killed in that case. I would recommend saving any state in didReceiveMemoryWarning, calling the base class, and in viewDidLoad restore the state.

I don't know why a controller would take a long time to load unless something it needs has been completely unloaded.