viewDidLoad being called when performing segue

Good Day All,


I am working on a new app and testing this on iOS 10 Beta, and using XCode 8 Beta.


I have a very simple app right now, which starts out with a view containing an imageView, and a UIButton. When you hit the button a call is made to a specified URL, and then a segue is performed, presenting a new view. Pretty simple.


For some reason, when the segue is performed, the view presenting the new view, is reloading. viewDidLoad is being called again, and of course all my setup and methods I may be calling, are called again.


If I comment out my performSegue line, this doesn't happen. I have tried with putting code in the prepareForSegue block, and without that even being there, and same thing happens.


To do a test, I placed a NSLog in the second view's viewDidLoad block, and I see the print to the console while other log entries being displayed from the current view.


I am simply calling:


[self performSegueWithIdentifier:@"segueName" sender:nil];


I am assuming this is a but in Xcode 8 / iOS 10? Has anybody else had this issue?


I have tried changing the segue behavior, animate, not animate, transition, etc etc. Same thing.

Answered by junkpile in 151700022

See, now we're getting somewhere 😀


Your ActiveViewController class extends from ViewController, so when you call [super viewDidLoad], that is calling the superclass's implementation, which performs the segue again, etc. etc.


It should probably extend from UIViewController instead.

I just tried running this on a iOS 9.3.2 device, and same thing happens. So certainly an issue with XCode 8?

This is still the case with XCode 8 Beta 2.


I created a whole new project from scratch and tried again, same thing.

Okay, something very strange is going on. I just tried doing this with Xcode 7 and the same thing happens...so I guess its not XCode 8 or iOS 10 as originally thoguh. I have never had this issue before.


Why is the view I am presenting from being reloaded when presenting another view? I have some scripts running in the background, making a web call to an API for example, and based on the response do something. In this case another view is being presented. Problem is it gets presented over and over and over and over and over............because the view reloads so the call to the API is made and so the condition occurs and so the new view is presented, and so it happens over and over...


Does anybody have any ideas?

Not without seeing some of the code involved.


Perhaps if you set a breakpoint and look at the stack trace in viewDidLoad you will see some clues. But it's impossible for anyone to guess with the amount of information you've given.

Sorry, I am obviously not being clear as I thought I was. I didn't see the need to provide code.


Okay, so, I have created a brand new single view application. I add a new ViewController class called ActiveViewController. In the viewDidLoad block I place a NSLog stating that view did load from ActiveViewController. I do the same in ViewController.m in the viewDidLoad with a NSLog stating that view did load from ViewController.


I create a method called goToActiveViewController which calls the performSegue method, using the identifier I am about to setup in the storyboard.


Back in the viewDidLoad method of ViewController, I add a delayed execution of the new goToActiveViewController method.


In the storyboard I add a new view controller, assign the ActiveViewControler class. Link ViewController to ActiveViewController with a present modally segue. This is the just of it.


When I run the application, after the time per the delayed execution, ActiveViewController loads and displays, I see the log entry in the console, BUT, at the same time see the ViewController NSLog at the same time! And leaving the app running, again after the time specified in the delayed execution, it happens again, both logs, and then again...so this is my overall issue. Why is viewDidLoad being called in the controller which is presenting the new view controller?


I originally thought this was a bug in XCode 8, or perhaps an issue with iOS 10 Beta 1, but still had the issue with Beta 2 for XCode and iOS 10. I then, using Xcode 8, loaded the app on my iPad which I have iOS 9.3.2 on, and same thing! So this ruled out iOS 10. I then recreated the app in XCode 7, and same thing! Something is wrong on my MacBook, obviously.


To proove this theory, I loaded up OS X on my Parallels Desktop app, and proceeded to create the same simple app in a brand new environment, and it worked as expected! So now I know there is something up with my instalation, but what is it? How is this happening?


Here is the final code of the simple app.


ViewController.h


#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end


ViewController.m


#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"View Did Load from View Controller");

    [self performSelector:@selector(goToActiveViewController) withObject:nil afterDelay:3.0];

}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}
-(void)goToActiveViewController {

    [self performSegueWithIdentifier:@"activeViewControllerSegue" sender:nil];

}
@end



ActiveViewController.h


#import <UIKit/UIKit.h>
@interface ActiveViewController : ViewController
@end


ActiveViewController.m


#import "ActiveViewController.h"
@interface ActiveViewController ()
@end
@implementation ActiveViewController
- (void)viewDidLoad {
    [super viewDidLoad];
  
    NSLog(@"View Did Load from Active View Controller");
  
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
@end


As you can see, super simple...

What is going on?

Accepted Answer

See, now we're getting somewhere 😀


Your ActiveViewController class extends from ViewController, so when you call [super viewDidLoad], that is calling the superclass's implementation, which performs the segue again, etc. etc.


It should probably extend from UIViewController instead.

junkpile, great catch!


That was such a stupid mistake on my part. I never even saw that. I was too fedup and upset with what was going on, that I completely missed why it was going on. Just like a missing semi-colon, although Xcode is great at pointing that out.


Now everything makes complete sense.


Thank you so much for saving my day! I was seriously sure something was wrong with my compiler or something. As embarrasing as that is to admit.


But hey, lesson learned.


Thank you.

viewDidLoad being called when performing segue
 
 
Q