【问题标题】:Unexpectedly found nil while unwrapping an optional yet the variable has a value解开可选变量时意外发现 nil 但变量有值
【发布时间】:2018-08-10 19:08:42
【问题描述】:

我正在制作一个简单的待办事项列表应用程序。我创建了一个自定义tableviewcell,其中包含一个标签和一个textview。标签用于标题,textview 用于描述。当我尝试运行该应用程序时,它崩溃并出现以下错误:

线程 1:致命错误:在展开可选值时意外发现 nil

在线抛出错误:

cell.taskTitle.text = task.title

但是上面一行的打印语句打印出"Optional("Task 1")"。 这是为什么呢?

这是整个函数:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath)
        as! TaskTableViewCell

    let task = taskList[indexPath.row]
    print(task.title)
    cell.taskTitle.text = task.title
    cell.taskDescription.text = task.description

    return cell
}

谢谢!

编辑: 我的 taskList 全局声明为:

var taskList: [Task] = [
    Task(title: "Task 1", desc: "Task 1 desc"),
    Task(title: "Task 2", desc: "Task 2 desc"),
    Task(title: "Task 3", desc: "Task 3 desc")
]

我的任务类:

class Task {
var title: String?
var description: String?

init(title: String, desc: String) {
    self.title = title
    self.description = desc
}

}

【问题讨论】:

  • 我相信问题出在您对任务的定义中。你能展示你如何声明 taskList 以及你如何声明你的任务对象吗?
  • 您可以将 Optional 视为另一个对象的容器对象,如果您使用 !运算符和 Optional 为 NIL 将导致运行时异常
  • 您可能还想检查您的 TaskTableViewCell 定义,如果您的 IBOutlet 有!将它们替换为 ?或仔细检查这些插座是否正确连接。
  • 如果属性在init 方法中被初始化为非可选,则不得将属性声明为可选。永远不要那样做。去掉问号。令人惊讶的是,代码确实可以编译,并且您的 Optional("Task 1") 意外行为消失了。
  • 删除问号后我仍然遇到同样的错误。然而,打印语句现在打印“任务 1”

标签: ios swift uitableview


【解决方案1】:

那是因为你找错地方了。 nil 不是 task.title。是cell.taskTitle

当然,现在您可能想知道为什么。这是因为您错误地配置了单元出队机制。你没有展示你是如何做到的,所以我们必须猜测。这里的一个常见错误是调用

tableView.register(TaskTableViewCell.self...

这实际上会防止您的单元格从情节提要或 xib 文件中加载,因此您单元格的所有出口都是nil。如果你的代码中有这样的一行,那么:

  • 如果单元格是在情节提要中设计的,请删除该行。

  • 如果您的单元格是在 xib 文件中设计的,则将该行替换为:

    tableView.register(UINib(nibName:"TaskTableViewCell", bundle:nil)...
    

【讨论】:

  • 我删除了那行,现在它给了我错误:libc++abi.dylib: terminating with uncaught exception of type NSException 显然这与引用插座有关?
  • 有趣。但是,错误通常会说得更多(在 Xcode 的控制台窗格中);你看看有没有?
  • 它在开头也这么说:2018-08-10 21:31:10.010093+0100 Someday[41553:1623841] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:'无法将标识符为 taskCell 的单元格出列 - 必须为标识符注册一个 nib 或一个类,或者在情节提要中连接一个原型单元格
  • 我刚刚更改了所有单元格引用等,我不再收到 NSInternalInconsistencyException。然而,现在,我又回到了第一个问题,在展开可选项时找到了 nil
  • 解决了!我不得不改变 let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) 为! TaskTableViewCell to: let cell = Bundle.main.loadNibNamed("TaskTableViewCell", owner: self, options: nil)?.first as! TaskTableViewCell
【解决方案2】:

首先,如果您使用诸如“po”之类的命令来显示每个变量的值以查看它是否已创建,那会更好其次,我在使用 willdispaly 函数之前遇到了这个问题,这是一个属性表格视图,它有很大的力量,它告诉你,表格视图单元格完成了加载,将要显示在以这种方式显示之前,你还想在其中更改任何内容,你确定一切都构建得很好没有零数

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多