我的Swift编写的iOS应用程序中有一个UITableView
。此UITableView
有2个类:TableViewController
用于控制表格,TableViewCell
用于控制UITableView
的单元格。
在HomeViewController
上我从DynamoDB中加载2件事,来自名为items
的表中的项目数组,以及Int
变量,其中包含名为{{1}的数组中的项目数}。我知道这些值并不是零,因为我将它们打印到控制台进行检查,然后我在控制台中打印出有效的结果。
在numberOfItems
方法上,我有以下代码:
tableView(numberOfRowsInSection:)
方法中的print函数返回控制台应该有的确切项目数。
on override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("numberOfRowsInSection", HomeViewController.GlobalVars.numberOfItems)
return HomeViewController.GlobalVars.numberOfItems
}
方法我有这段代码:
tableView(cellForRowAt:)
现在,代码中没有理解的一些事情:
1)override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "TableViewCell"
self.tableView.register(TableViewCell.self, forCellReuseIdentifier: cellIdentifier)
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? TableViewCell else {
fatalError("The dequeued cell is not an instance of TableViewCell.")
}
print("indexPath.row", indexPath.row)
let item: Item = HomeViewController.GlobalVars.items[indexPath.row]
let name: String = item.name!
cell.itemNameLabel.text? = name
return cell
}
是我的DynamoDB对象映射器
2)Item
是itemNameLabel
UILabel
TableViewCell
,我使用Ctrl + Drag
从故事板连接到TableViewCell
文件。
3)我打印indexPath.row
的值因为我之前遇到了Index out of range
的致命错误,所以我添加了这个打印函数来检查索引是否在范围内(是。)
4)要检查name
字符串是否有效,我已添加此行以进行检查:
print("name", name)
我得到了该项目的名称,没有在控制台上打印任何错误。
目前的问题是每当我运行此代码时,我都会在控制台上收到此错误日志:
numberOfRowsInSection 3
numberOfRowsInSection 3
numberOfRowsInSection 3
numberOfRowsInSection 3
indexPath.row 0
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
正如您所看到的,由于某种原因,它会打印numberOfRowsInSection
4次,有时会打印3次。
它一直运行到我将UILabel
的文本设置为变量的行,但后来我得到了致命的错误消息。错误显示在我设置文本的行上,并显示以下错误消息:
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0)
字符串本身可能是有效的,因为当我打印name
变量时,我得到了应该得到的值。
我该怎么做才能解决这个问题,并在UILabel
的{{1}}上显示价值?
编辑#1 :
DynamoDB Object Mapper中的变量是选项:
UITableView
答案 0 :(得分:3)
可选项可以保留值或零。
除非你确定它包含非零值,否则不要强行打开一个可选项。
let name: String = item.name
cell.itemNameLabel.text = name
cell.itemNameLabel.text
也是可选的,因此您无需解开item.name
。答案 1 :(得分:1)
<强>可能性。强>
此崩溃可能有两种可能性。
正如您尝试if let
并尝试删除强制解包后,他们只有一次机会可能是您的标签出口与您的故事板实例无关。可能是你的标签是零。
如果出于某种原因删除了标签连接,请检查标签连接,然后请再次创建该出口。
要测试它,请删除为label指定名称的代码行。
只需为其分配一个空字符串,如果它仍然崩溃,那么确保您的Label为零。
答案 2 :(得分:0)
使用警卫或如果让我们避免此类崩溃。
正如cellForRowAt
方法中的最后三行
let name: String = item.name!
cell.itemNameLabel.text? = name
return cell
将上述代码更改为此内容。
if let name = item.name {
//If you get inside this if block it means your name variable is not nil.
cell.itemNameLabel.text = name
}else {
//If you are in else block it means your name variable is nil.
//Assign Empty string to label.
cell.itemNameLabel.text = ""
}
return cell
这就是你如何摆脱这种崩溃。