明确展开可选的nil不会导致崩溃

时间:2018-03-29 15:26:01

标签: swift

之前有几个人问过这个问题,但没有接受答案。

我的Traceback (most recent call last): File "/home/user/.local/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2881, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-3-d4b38cb7b048>", line 4, in <module> for att_dict in att_dict_list] File "<ipython-input-3-d4b38cb7b048>", line 4, in <listcomp> for att_dict in att_dict_list] TypeError: unhashable type: 'list' 包含UITableViewCell

如果我在textField外略微点击该行突出显示。我想阻止这一点。

为防止这种情况,我会执行以下操作:

UITextField

这完全没问题。这是我的问题。本教程的作者说:

  

请注意,只有在存在时才允许从方法返回nil   返回类型后面的问号(或感叹号)。

他的意思是你可以在可选的返回类型后面添加一个感叹号。为什么程序没有崩溃?在IndexPath返回类型之后放置感叹号后返回nil并不会崩溃。我想 !将明确解开nil并失败????

2 个答案:

答案 0 :(得分:5)

从Swift 3开始,“Implicitly unwrapped optional”不是一个单独的类型, 但是常规/强选项声明的属性。 有关详细信息,请参阅SE-0054 Abolish ImplicitlyUnwrappedOptional type

具有IUO返回类型的函数可以返回nil, 并将返回值赋给变量使其成为常规变量 可选的:

func foo() -> Int! {
    return nil
}

let x = foo() // Type of `x` is `Int?`
print(x) // nil

仅当评估作为可选项不可用时才是值 将被强制解包(并导致运行时异常 值为nil):

let y = 1 + foo() // Fatal error: Unexpectedly found nil while unwrapping an Optional value

在你的情况下,你的

override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath!

方法会覆盖UITableViewController方法

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?

并且可以返回nil。除非呼叫者解开,否则这不会崩溃 价值。

备注:以上内容是解释您的代码编译的原因 和工作。一般来说,我没有看到隐含使用的充分理由 展开的可选返回类型。 IUO的主要用例是 在SE-0054中说明:

  

ImplicitlyUnwrappedOptional(“IUO”)类型是用于导入Objective-C API的有用工具,其中未指定参数或返回类型的可为空性。它也代表了一种在初始化器中处理明确初始化问题的便捷机制。

答案 1 :(得分:0)

将此视为API实现者的选择的一种方法。如果实现者处理输入参数,那么API用户就不会有任何问题。

让我们创建一个只在控制台上打印的绘图文本类。

class TextDrawer {

  var mustBeText: String!

  func renderText(string: String) {
      print(string)
  }

  func renderSafely() {
     renderText(string: self.mustBeText ?? "Nothing found to be rendered")
     // or 
     if let safeString = self.mustBeText {
        renderText(string: safeString)
     }
  }

  func renderUnsafely() {
      renderText(string: mustBeText)
  }
}

我们已将mustBeText定义为String!意味着我们可以期待任何字符串以及nil参数。

现在,我们创建一个类的实例,如下所示:

let textDrawer = TextDrawer()
textDrawer.mustBeText = nil // this is allowed since the `mustBeText` is `String!`.

textDrawer.renderSafely() // prints -- Nothing found to be rendered

textDrawer.renderUnsafely() // crashes at runtime.

renderUnsafaly()因为未处理nil案件而崩溃。