简体   繁体   中英

loadview getting called infinite times

I have two ViewControllers in my app ViewController1.m and ViewController2.m .

In AppDelegate I am having this code.

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
    self.viewController = [[ViewController1 alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
}
else
{
    self.viewController = [[ViewController1 alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
}


self.window.rootViewController = self.viewController;

[self.window makeKeyAndVisible];

In ViewController1.m I have added a button and on button click I am displaying another view controller ViewController2.m like this:

ViewController2 * obj = [[ViewController2 alloc] initWithNibName:nil bundle:nil];

[self.view addSubview:obj.view];

In the loadView of ViewController2.m I am adding another button like this

NSLog(@"\n Load view called");

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[button addTarget:self action:@selector(onButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

[button setTitle:@"Back to previous view" forState:UIControlStateNormal];

button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);

[self.view addSubview:button];

When I run my app, on clicking the button present in ViewController1.m the app hangs and loadView of ViewController2.m starts getting called infinitely.

I dont know the reasin behind this problem, I just wanted to load another ViewController on a button click and I am not using any Navigation Controller.

Can someone point out the reason behind this issue?

Don't do this in loadView . Instead move your code to viewDidLoad . The problem is you're accessing self.view within loadView , which basically calls loadView since the initial call to loadView never returned.

Sorry for the tongue twister... loadView is called automatically when the view hasn't yet been instantiated. Only when it returns is the view initialization complete. If it hasn't return and you try to access the view property, it'll call it again. And in your case, it's recursive because you are still in the loadView method.

From the docs :

The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.

When you use initWithNibName do not oveeride loadView . Its a wrong design. If you do not want to use viewDidLoad and want to something in initialize phase, then override this method,

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

The exclusive job of loadView is to set the viewControllers view property. That could be something like

self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];

Imagine that the getter of your view property looks something like this:

 if(!_view)
     [self loadView];

  return _view;

This means that if you use self.view before setting the view (like in loadView), loadView will be called over and over again. My advice is typically to avoid overriding loadView and instead create a simple configureView method that is called from both awakeFromNib and initWithNib... so the view can be created properly either from a storyboard or nib or instantiated by code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM