为啥在我的 RootViewController:viewDidLoad 方法之后突然调用我的应用程序委托的 didFinishLaunchingWithOptions 方法?

Posted

技术标签:

【中文标题】为啥在我的 RootViewController:viewDidLoad 方法之后突然调用我的应用程序委托的 didFinishLaunchingWithOptions 方法?【英文标题】:Why is my app delegate's didFinishLaunchingWithOptions method all of sudden being called AFTER my RootViewController:viewDidLoad method?为什么在我的 RootViewController:viewDidLoad 方法之后突然调用我的应用程序委托的 didFinishLaunchingWithOptions 方法? 【发布时间】:2010-05-17 23:15:32 【问题描述】:

我一直在 Xcode 中使用 iPad 的 SplitView 模板。以下是基于拆分视图的应用程序模板为您自动生成的许多重要方法中的两个...

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();
    

在进行任何更改之前构建和运行项目时,application:didFinishLaunchingWithOptions 方法会在 RootViewController:viewDidLoad 方法被调用之前被调用。我是 iPhone 开发的新手,但我假设这是正确且典型的顺序。所以这是我所做的更改......

一旦我确认一切正常且没有任何修改,我更改了 RootViewController 代码并将其设置为 UIViewController 的子类(而不是默认情况下的 UITableViewController),并在 Interface Builder 中进行了相应的调整。我构建并运行,一切仍然正常。 然后,我在 IB 的 RootView 中添加了一个 UIView(其中没有任何内容),当我构建并运行它时,突然在 application:didFinishLaunchingWithOptions 方法之前调用了 RootViewController:viewDidLoad

我需要让它恢复到之前的工作方式,因为正如您在代码中看到的那样,viewDidLoad 方法依赖于 didFinishLauchingWithOptions 方法来执行,因此它可以设置它用来执行的 rootViewController 的 managedObjectContext获取请求。

    任何想法是什么原因造成的? 有什么办法可以解决这个问题吗?

非常感谢您的帮助!我会继续研究和使用代码。

【问题讨论】:

【参考方案1】:

模板app中-applicationDidFinishLaunching将RootViewController的view添加到window中,导致view加载,所以很明显-viewDidLoad会跟在-applicationDidFinishLaunching后面。

ViewDidLoad 是(间接)从 applicationDidFinishLaunching 调用的。

如您所说,如果 viewDidLoad 在 applicationDidFinishLaunching 之前被调用,那是因为您在调用 applicationDidFinishLaunching 之前做了一些事情来导致视图加载。

您是否在 -viewDidLoad 中添加了断点并查看堆栈跟踪以了解调用它的原因?

【讨论】:

【参考方案2】:

你在哪里初始化RootViewController?通常,您在applicationDidFinishLaunching 中执行此操作(至少在 iPhone 上)。如果您在应用程序委托的 init 方法中对其进行初始化,这可能会导致在 applicationDidFinishLaunching. 之前调用根视图控制器的 viewDidLoad 方法

【讨论】:

谢谢,伙计!基于 SplitView 的应用程序模板不会为 RootViewController 生成任何初始化代码,至少我在任何地方都看不到它。因此,由于我是 iPad 开发的新手,并且基于到目前为止我自学的内容,我将假设 RootViewController 的初始化逻辑嵌入在主窗口的 nib 文件中,因为大多数 UI 都是在IB,对吧?【参考方案3】:

这可能是因为在 MainWindow.xib 中,您的应用程序委托对象未连接到文件的所有者 (UIApplication)。您可以打开 MainWindow.xib 并右键单击您的 App Delegate 以查看它在引用 Outlet 到 File's Owner 中是否有连接。如果没有,请将其设置为。这将解决您的问题。

【讨论】:

以上是关于为啥在我的 RootViewController:viewDidLoad 方法之后突然调用我的应用程序委托的 didFinishLaunchingWithOptions 方法?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的模态呈现(表单)navController 的 rootViewController 在模态呈现时不知道它的尺寸较小?

为啥我的 segue 不等到完成处理程序完成?

为啥模拟器中没有出现导航栏?

RootViewController 中的方法不存储数组

为啥添加到我的导航项的按钮看起来不活动?

为啥在 SwiftUI Lifecycle 中将 rootViewController 设置为 UIHostingController 时会出错?