我对Swift比较新。在做一些阅读时,我找到了以下示例代码,用于在app delegate中以编程方式创建UINavigationController:
let mainVC = ViewController.init()
let nc = UINavigationController.init(rootViewController: mainVC)
self.window = UIWindow.init(frame: UIScreen.main.bounds)
self.window!.rootViewController = nc
self.window?.makeKeyAndVisible()
我的问题涉及最后一行“ self.window?.makeKeyAndVisible()”。我原以为它会用到!解开self.window类似于上面的行,但相反?被使用了。我试过这两个代码!和?在这两种情况下,应用程序都已编译并成功运行。
我想知道的是哪个标点符号(!或?)最适合使用,为什么请使用?
答案 0 :(得分:4)
请考虑以下代码段:
var tentativeVar: Array<Any>?
tentativeVar = Array()
tentativeVar?.append("FirstElement")
现在,如果您使用可选的展开打印tentativeVar(使用?),您将获得以下结果。
(lldb) po tentativeVar?[0]
Optional<Any>
- some : "FirstElement"
对于相同的情况,如果您强行打开变量,您可以直接获取该对象,省略不必要的可选数据。
(lldb) po tentativeVar![0]
"FirstElement"
对于同一个对象,如果您没有初始化对象并尝试访问其中的元素,则会发生以下情况。
print("\(tentativeVar?[0])") //prints nil
print("\(tentativeVar![0])") //Crashes the app, trying to unwrap nil object.
答案 1 :(得分:1)
您所看到的是optional chaining。它与可选的展开略有不同,因为您并不总是将结果赋值给变量。
如果self.window!.rootViewController = nc
为零,则 window
会崩溃。
如果self.window?.rootViewController = nc
为零,则window
将不执行任何操作。
如果您没有将链条分配给变量,强制展开链条没有任何好处,因此通常最好使用?
,除非您希望应用程序崩溃为零(如果您执行希望如此,我建议改为实现自己的错误处理,报告错误的一些细节。