Infinite loop when using loadView

4.1k views Asked by At

Very interesting problem when using loadView in UIViewController.

Usually we used like this way

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
    NSLog(@"loadview");
    [super loadView];
}

If remove

 [super loadView];

We will get dead loop with this

- (void)loadView {
    NSLog(@"loadview");

}

Why ?

3

There are 3 answers

0
petershine On BEST ANSWER

Since you are just INHERITING what's being implemented in super class(UIViewController), if you don't call super methods, then implementation that needs to be done is NOT done.

Almost all super methods do something critical and the local class inheriting super class implementations must either override them all together (unless you know everything about what super does by referring to the documentation, it's never a good idea), or just ADD local class implementation to the inherited super class implementations.

In conclusion, whenever you inherit a class, which is in most cases of software development, you should let the super class do its implementations unless it's safe to override them.

If I am correct, it seems like super loadView implements something very critical to avoid the loop.

ADDITIONAL NOTE: However, based on the documentation, you should not call super method: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html Probably, the reason for infinite loop is caused by not implementing view property appropriately.

0
er0 On

If you override loadView, you are expected to provide a root view for the controller's view hierarchy. If you don't provide it loadView would get called every time the view is referenced, possibly leading to an infinite loop. From the docs:

If you specify the views manually, you must implement the loadView method and use it to assign a root view object to the view property.

Implementations that would cause an infinite loop:

- (void)loadView {
    NSLog(@"loadview");
}

...self.view is nil after loadView

- (void)loadView {
   self.view; // Or anything that references self.view
}

...referencing self.view causes loadView to be invoked, hence an infinite loop.

Correct:

- (void)loadView {
    self.view = [[UIView alloc] init];
    if (self.view == nil) {
        [super loadView]; // Try to load from NIB and fail properly, also avoiding inf. loop.
    }
}
0
Jlexyc On

Only one way to make infinite loop in this case - is getting view property until its not set. If you write next (for example):

- (void)loadView {
   self.view = [[UIView alloc] initWithFrame:self.view.bounds];
}

You'll got infinite loop, but

- (void)loadView {
   self.view = [[UIView alloc] initWithFrame:CGRectZero];
}

works OK.

So you can't to access view property until you didn't set it.