为什么 AppDelegate.swift window 是可选的?

Why is AppDelegate.swift window an optional?

我正在阅读Apple docs,当我发现这句话时:

The AppDelegate class contains a single property: window.

var window: UIWindow?

This property stores a reference to the app’s window. This window represents the root of your app’s view hierarchy. It is where all of your app content is drawn. Note that the window property is an optional, which means it may have no value (be nil) at some point.

我不明白的是:为什么这个 属性 在某些时候可能是零?它是(来)零的情况是什么?

您可能并不总是需要它。比如调用这两个方法时:

application(_:performFetchWithCompletionHandler:)
application(_:handleEventsForBackgroundURLSession:completionHandler:)

您的应用不会向用户显示,因此不需要 window

一如既往,更多内容在docs

现在,我不确定这是内在原因,但它似乎是一个很好的可能性(至少对我而言)。不过,如果有人能够提供更多信息,我也很乐意了解更多信息。

当您以编程方式创建 window 而不是使用主情节提要时,它会变得更加明显,主情节提要会自动设置 window 属性。

您可能不希望或无法在创建委托对象(在您的情况下为 AppDelegate)时立即创建 window。通常您不需要创建 window 并设置 属性 直到 application(_:didFinishLaunchingWithOptions:) 被调用。因此,在创建 window 并设置 属性 之前,它将是 nil.
与 Losiowaty 一样,当应用程序启动但未向用户显示时也是这种情况 - 例如当只是在后台处理位置更新或其他信息时。

如果 属性 是非可选的,那么您将被迫在创建 AppDelegate 对象时创建 window,这既不需要也不需要。

当您关闭您的应用程序时,您的应用程序仍然可以在后台接收silentNotifications或下载数据、跟踪您的位置、播放音乐等。

在下图中,圈出的 红色 表示您的应用仍在 某事,但是它不再 屏幕上。它在后台,所以 AppDelegate 不再需要 window。结果它将被设置为 nil

简单概述


详细概览

FWIW,下面的代码 不会 使应用程序以 vc 启动。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        let vc = ViewController()
        window?.rootViewController = vc
        window?.makeKeyAndVisible()
        return true
    }

为什么不起作用?因为window属性是可选的——初始设置为nil。需要实例化

下面的代码可以工作

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let vc = ViewController()
    window = UIWindow(frame: UIScreen.main.bounds) // Now it is instantiated!!
    window?.rootViewController = vc
    window?.makeKeyAndVisible()
    return true
}