为什么 "var delegate: UIApplicationDelegate?" 在 UIApplication 中成为可选项?那会是致命错误吗?
Why is "var delegate: UIApplicationDelegate?" made an optional in UIApplication? That'd be a fatal error?
如果 delegate
属性 曾经是 nil
,应用程序将处于不可恢复的状态。
class UIApplication
Declaration
unowned(unsafe) var delegate: UIApplicationDelegate?
Discussion
Every app must have an app delegate object to respond to app-related messages. For example, the app notifies its delegate when the app finishes launching and when its foreground or background execution status changes. Similarly, app-related messages coming from the system are often routed to the app delegate for handling. Xcode provides an initial app delegate for every app and you should not need to change this delegate later.
为什么 UIApplicationDelegate.delegate
定义为可选? nil
值将无法恢复?
实际上,如果我将 UIApplication 子类化,那么我可能能够从 delegate
设置为 nil
恢复?这可能是为什么?
这里是 ,但 AppDelegate
是将整个应用程序整合在一起的东西。我不认为它可能是 nil
.
为了了解 why/how 这是否有效,您必须了解 UIApplication 的内部工作原理,因此关于它为什么或为什么不是可选的任何想法都纯粹是猜测。
可能有一点,如果委托为 nil,应用程序要么退出或崩溃,要么只是允许初始化而不设置委托,他们选择不强制展开它,以便他们可以处理错误情况。
一个原因可能是为了防止 AppDelegate 弄乱您的单元测试。
通常,当您进行 运行 单元测试时,实际上您不必与屏幕上绘制的任何 UI 组件进行交互,因此初始化应用程序的 window
属性 完全没有必要。此外,在 AppDelegate.swift
中编写的代码(例如 application(application:didFinishLaunchingWithOptions
中的函数调用)可能会导致您的单元测试无法按预期 运行 进行,因此您可能希望应用程序委托永远不会被实例化。
对于典型的 iOS 应用程序,UIKit 在 main.swift
中使用以下函数创建应用程序:
UIApplicationMain(Process.argc, Process.unsafeArgv,
NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate))
(从 Xcode 6 开始,它由 @UIApplicationMain
装饰器处理。)
UIApplicationMain
初始化应用程序对象和类型为您传递给它的 class 名称的应用程序委托,并设置事件循环。让它为您创建委托对象完全取决于您。如果您不需要 AppDelegate 的 UIWindow
属性,或任何关于处理推送通知、应用程序状态等的回调方法,您可以在没有它的情况下创建应用程序:
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), nil)
也就是说,如果您的单元测试不依赖于 AppDelegate 的任何方法 运行,您可以按如下方式更新 main.swift
:
var delegateClassName: String? = NSStringFromClass(AppDelegate)
if NSClassFromString("XCTestCase") != nil {
// Unit tests are being run, so don't execute any code written in AppDelegate.swift
delegateClassName = nil
}
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), delegateClassName)
如果 delegate
属性 曾经是 nil
,应用程序将处于不可恢复的状态。
class UIApplication
Declaration
unowned(unsafe) var delegate: UIApplicationDelegate?
Discussion
Every app must have an app delegate object to respond to app-related messages. For example, the app notifies its delegate when the app finishes launching and when its foreground or background execution status changes. Similarly, app-related messages coming from the system are often routed to the app delegate for handling. Xcode provides an initial app delegate for every app and you should not need to change this delegate later.
为什么 UIApplicationDelegate.delegate
定义为可选? nil
值将无法恢复?
实际上,如果我将 UIApplication 子类化,那么我可能能够从 delegate
设置为 nil
恢复?这可能是为什么?
这里是 AppDelegate
是将整个应用程序整合在一起的东西。我不认为它可能是 nil
.
为了了解 why/how 这是否有效,您必须了解 UIApplication 的内部工作原理,因此关于它为什么或为什么不是可选的任何想法都纯粹是猜测。
可能有一点,如果委托为 nil,应用程序要么退出或崩溃,要么只是允许初始化而不设置委托,他们选择不强制展开它,以便他们可以处理错误情况。
一个原因可能是为了防止 AppDelegate 弄乱您的单元测试。
通常,当您进行 运行 单元测试时,实际上您不必与屏幕上绘制的任何 UI 组件进行交互,因此初始化应用程序的 window
属性 完全没有必要。此外,在 AppDelegate.swift
中编写的代码(例如 application(application:didFinishLaunchingWithOptions
中的函数调用)可能会导致您的单元测试无法按预期 运行 进行,因此您可能希望应用程序委托永远不会被实例化。
对于典型的 iOS 应用程序,UIKit 在 main.swift
中使用以下函数创建应用程序:
UIApplicationMain(Process.argc, Process.unsafeArgv,
NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate))
(从 Xcode 6 开始,它由 @UIApplicationMain
装饰器处理。)
UIApplicationMain
初始化应用程序对象和类型为您传递给它的 class 名称的应用程序委托,并设置事件循环。让它为您创建委托对象完全取决于您。如果您不需要 AppDelegate 的 UIWindow
属性,或任何关于处理推送通知、应用程序状态等的回调方法,您可以在没有它的情况下创建应用程序:
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), nil)
也就是说,如果您的单元测试不依赖于 AppDelegate 的任何方法 运行,您可以按如下方式更新 main.swift
:
var delegateClassName: String? = NSStringFromClass(AppDelegate)
if NSClassFromString("XCTestCase") != nil {
// Unit tests are being run, so don't execute any code written in AppDelegate.swift
delegateClassName = nil
}
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), delegateClassName)