为什么"var delegate: UIApplicationDelegate?"在UIApplication中成为可选内容?那会是一个致命的错误吗?



如果delegate属性为nil,则应用程序将处于不可恢复状态。

UIApplication

声明


无主的(不安全的)var delegate: UIApplicationDelegate?

每个应用都必须有一个应用委托对象来响应与应用相关的消息。例如,当应用程序完成启动以及前台或后台执行状态发生变化时,应用程序通知其委托。类似地,来自系统的与应用相关的消息通常被路由到应用委托进行处理。Xcode为每个应用提供了一个初始的应用委托,以后你不需要修改这个委托。

为什么将UIApplicationDelegate.delegate定义为可选项?nil值是不可恢复的?

实际上,如果我子类UIApplication那么我可能能够从delegate设置到nil恢复?这可能是原因吗?

这是一个相关的问题,但是AppDelegate是将整个应用程序连接在一起的东西。我觉得不可能是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初始化应用程序对象和应用程序委托,其类型是您传递给它的类名,并设置事件周期。让它为你创建委托对象完全取决于你。如果你不需要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)

为了知道为什么/如何工作,你必须知道UIApplication内部是如何工作的,所以任何关于为什么或为什么不是可选的想法都是纯粹的猜测。

如果委托为nil,应用程序可能会退出或崩溃,或者只是允许初始化而不设置委托,他们选择不强制展开它,以便处理错误情况。

相关内容

最新更新