Why is my app delegate's didFinishLaunchingWit

2019-01-25 15:12发布

问题:

I've been playing with the iPad's SplitView template in Xcode. Here are two of the many important methods that are auto-generated for you by the Split View-based Application template...

AppNameAppDelegate.m

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after app launch    
    rootViewController.managedObjectContext = self.managedObjectContext;


    // Add the split view controller's view to the window and display.
    [window addSubview:splitViewController.view];
    [window makeKeyAndVisible];

    return YES;
}

RootViewController.m

#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {

    [super viewDidLoad];
    self.clearsSelectionOnViewWillAppear = NO;
    self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

When you build and run the project before making any changes at all, the application:didFinishLaunchingWithOptions method is called before the RootViewController:viewDidLoad method is called. I'm new to iPhone development, but I'm assuming this is the correct and typical sequence. So here are the changes I made...

  • Once I confirmed everything was working without any modifications, I changed the RootViewController code and set it as a subclass of UIViewController (instead of UITableViewController by default) and made the respective adjustments in Interface Builder. I built and ran, everything was still working fine.
  • Then, I added a UIView (with nothing in it) to the RootView in IB and when I built and ran it, suddenly the RootViewController:viewDidLoad is being called before the application:didFinishLaunchingWithOptions method.

I need to get it back to the way it was working before because, as you can see in the code, the viewDidLoad method depends on didFinishLauchingWithOptions method to execute so it can set the rootViewController's managedObjectContext that it uses to perform the fetch request.

  1. Any ideas what caused this?
  2. Any ideas how I can fix this?

Thanks so much in advance for your help! I'm gonna keep researching and playing with the code.

回答1:

In the template app -applicationDidFinishLaunching adds RootViewController's view to the window, causing the view to load, so obviously -viewDidLoad will follow - applicationDidFinishLaunching.

ViewDidLoad is (indirectly) called from applicationDidFinishLaunching.

If, as you say, viewDidLoad is being called before applicationDidFinishLaunching it is because you have done something to cause the view to load before applicationDidFinishLaunching is called.

Did you add a breakpoint in -viewDidLoad and look at the stacktrace to see what was responsible for calling it?



回答2:

Where are you initializing RootViewController? Typically, you do so in applicationDidFinishLaunching (at least on the iPhone). If you are initializing it in your app delegate's init method, that could cause the root view controller's viewDidLoad method to be invoked before applicationDidFinishLaunching.



回答3:

This is propabaly caused by the fact that in MainWindow.xib, your application delegate object is not connected to File's Owner (UIApplication). You can open the MainWindow.xib and right click on your App Delegate to see if it has a connection in Referencing Outlet to File's Owner. If not, set it to. And this will fix your problem.