Swift可选的解包语法

时间:2017-05-15 13:06:58

标签: ios swift

我对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类似于上面的行,但相反?被使用了。我试过这两个代码!和?在这两种情况下,应用程序都已编译并成功运行。

我想知道的是哪个标点符号(!或?)最适合使用,为什么请使用?

2 个答案:

答案 0 :(得分:4)

  1. 如果使用?如果对象为空,则解包对象,应用程序不会崩溃。(?符号将跳过展开,假设对象为零)
  2. 如果你使用!解包对象,如果对象为null,则应用程序将崩溃。 (你使用!当你期望对象时,它永远不会是零)。
  3. 请考虑以下代码段:

    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将不执行任何操作。

如果您没有将链条分配给变量,强制展开链条没有任何好处,因此通常最好使用?,除非您希望应用程序崩溃为零(如果您执行希望如此,我建议改为实现自己的错误处理,报告错误的一些细节。