实现UIApplicationDelegate协议的窗口属性

时间:2016-08-18 14:44:08

标签: ios

假设我不使用故事板。在我在windowwillFinishLaunchingWithOptions中初始化的应用程序委托中看到didFinishLaunchingWithOptions属性的所有示例中。为什么不在对象初始化步骤?我试着这样做,一切似乎都很好。

更新:更清楚。此代码是否包含任何隐藏的问题?

class MyAppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow? = UIWindow(frame: UIScreen.mainScreen().bounds)

    func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
        window?.rootViewController = UIViewController() //just template to make compile possible
        window?.makeKeyAndVisible()
        return true
    }
    /* ... */
}

1 个答案:

答案 0 :(得分:1)

我基于这个问题进行了实验和研究。

首先让我们看看UIApplicationDelegate的窗口属性上的Apple Docs:

  

如果您的应用的Info.plist文件包含UIMainStoryboardFile键,则需要实现此属性。幸运的是,Xcode项目模板通常会自动为应用程序委托包含属性的合成声明。此合成属性的默认值为nil,这会导致应用程序创建通用UIWindow对象并将其分配给属性。如果要为应用程序提供自定义窗口,则必须实现此属性的getter方法,并使用它创建并返回自定义窗口。

因此,如果您的代码未在Info.plist中使用UIMainStoryboardFile选项,则必须自行设置窗口。我的实验表明UIApplication根本没有调用window属性。 Getter仅在willFinishLaunchingWithOptions方法中调用。据我所知,这种方法没有隐藏的问题。

如果要使用UIMainStoryboardFile选项,可以将窗口创建保留给UIApplication。在应用程序的启动过程中,UIApplication检查Info.plist中的UIMainStoryboardFile键,如果提供了故事板,它将向AppDelegate询问窗口:

  • 如果window为nil,UIApplication会创建一个,为其分配rootViewController并在AppDelegate中设置它。
  • 如果窗口不是nil,UIApplication会为其分配rootViewController