-->

loadView called multiple times when view property

2020-07-16 03:04发布

问题:

I just came across something that I have not seen before and I thought I would ask here to verify the cause. I have a UIController who's view is defined programatically, I noticed today that when I commented the code out of its loadView (to test something else) that both loadView and viewDidLoad were both called four times. My thinking is that because I have not set the view property iOS is trying multiple times to load the view, although I am still a little curious if this is the case why viewDidLoad was also called.

- (void)loadView {
    NSLog(@"%s", __PRETTY_FUNCTION__);

    // MAP VIEW
    // MKMapView *tempMapView = [[MKMapView alloc] init];
    // [tempMapView setDelegate:self];
    // [self setView:tempMapView];
    // [self setCustomMapView:tempMapView];
    // [tempMapView release];
}

Console output:

2011-02-02 14:10:00.194 Xrails[19501:307] -[MapController loadView]
2011-02-02 14:10:00.209 Xrails[19501:307] -[MapController viewDidLoad]

2011-02-02 14:10:00.212 Xrails[19501:307] -[MapController loadView]
2011-02-02 14:10:00.226 Xrails[19501:307] -[MapController viewDidLoad]

2011-02-02 14:10:00.229 Xrails[19501:307] -[MapController loadView]
2011-02-02 14:10:00.243 Xrails[19501:307] -[MapController viewDidLoad]

2011-02-02 14:10:00.246 Xrails[19501:307] -[MapController loadView]
2011-02-02 14:10:00.259 Xrails[19501:307] -[MapController viewDidLoad]

回答1:

I think there's two points here. Firstly, I think your assumption is right in that whatever is calling for the view is getting nil back and so asks for the view controller's view again. This causes it to go through -loadView as documented for -view in the documentation for UIViewController.

As for why -viewDidLoad is being called afterwards, even though it hasn't loaded the view; I imagine that where -loadView is being called it is assumed that the view has been loaded and calls -viewDidLoad straight afterwards.

Either way, if you implement -loadView yourself, you must have a valid view at the end of it.



回答2:

Add [super loadView] at the beginning of the loadView method



回答3:

Put your code in viewDidLoad, and comment loadView method



回答4:

Your override of loadView must assign a view to self.view.

- (void)loadView 
{
   self.view = [UIView new];
}

Per docs at https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview

You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super.

Presumably there are several places deep down in UIKit where something like this gets called:

if (viewController.view == nil) {
    [viewController loadView];
}