It is my understanding that awakeFromNib will always be called before viewDidLoad.
So I have a subclass of a UITableViewController, which is unarchived from a xib file.
I defined these two methods inside:
- (void)awakeFromNib {
[super awakeFromNib];
NSLog(@"awake from nib");
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"view did load");
}
what happens is that "view did load" shows up before "awake from nib" in the console. I tried to use a breakpoint at [super awakeFromNib], and repeatedly hit F7 (Step Into), and to my surprise, it stepped into -(void)viewDidLoad BEFORE going to the second line inside awakeFromNib.
Does anyone have a clue what is going on here? I did the exact same thing in a subclass of a regular UIViewController, and the log statements are reversed, as I initially expected...
Without being an expert, and following this posts, I realise than in a Tab Controller scenario, In the "child" view controller, the awakeFromNib method is executed when tab controller (parent) is loaded, but viewDidLoad only when its "Tab" is clicked.
And, therefore I understand that this can be used to load data only when a specific tab is selected (clicked)
To understand that fact I recommend you to see
loadNibNamed:owner:options:
method ofNSBundle
.When you init a view controller from nib, first of all it loads views that are contained there, then it sets file owners properties according to nib.
viewDidLoad
method is called when it sets file owner'sview
property to one of the views that were loaded. AndawakeFromNib
is called when all file owners outlets and properties are set (includingview
property). So it makes sense thatviewDidLoad
is called earlier thanawakeFromNib
.Hope this'll help
I don't think you have to call awakeFromNib on your super class.
Check this.
Edit
I just ran a quick test, here's the results:
Scenario 1: MainWindow.Xib has a UIViewController subclass
TestingAwakeFromNibViewController
, Which has it's own Nib fileTestingAwakeFromNibViewController.xib
.TestingAwakeFromNibViewController has an UIButton Outlet called btn3. Testing the following code :
Would Print:
Scenario 2: Removing the xib file, adding a UIView as a son to the TestingAwakeFromNibViewController inside MainWindow.Xib, and adding UIButton as a subview to the UIView (and connecting the UIbutton outlet to the appropriate outlet of TestingAwakeFromNibViewController).
Now running the above code would print:
Meaning ViewDidLoad prior to AwakeFromNib.
Third Scenario: Same as the second, just without calling
[super awakeFromNib];
Now ViewDidLoad is not even getting called.
So, it seems like different scenarios are calling for different action, and we need to prepare ourselves according to the one we're acting upon.
I create a test project with Navigation-based Application option, and add following codes to rootViewController.m.
Then, I got the results from console:
The
-(void)viewDidLoad
will be called when the view of controller is loaded. So, when the first time you useself.view = ...
, the-(void)viewDidLoad
will be invoke.If you wrote something like followings, then
-(void)viewDidLoad
will be called first.and obtain following results.
Update
loadViewIfNeeded will trigger
viewDidLoad
if it loads view successfully. Sometimes I will call loadViewIfNeeded to ensure the@IBOutlet
instances were initialized, and not null anymore.