swift - 带有可选选项的致命错误没有意义
问题描述
我不断收到一个致命错误,说明一个值是如何解包的,它是 nil,我不明白如何。当我用特定变量实例化视图控制器时,它们都会显示出来,但是当我对确切的 VC 执行 segue 时,这些值不会显示出来。
以这些功能为例...
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let displayVC = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboards.TeachStoryboardID) as? SchoolEventDetailsViewController {
displayVC.selectedEventName = events[indexPath.row].eventName
displayVC.selectedEventDate = documentsDate[indexPath.row].eventDate
displayVC.selectedEventCost = documentsCost[indexPath.row].eventCost
displayVC.selectedEventGrade = documentsGrade[indexPath.row].eventGrade
displayVC.selectedEventDocID = documentsID[indexPath.row]?.docID
navigationController?.pushViewController(displayVC, animated: true)
}
}
这与此功能相结合:
func verifyInstantiation() {
if let dateToLoad = selectedEventDate {
dateEditableTextF.text = dateToLoad
}
if let costToLoad = selectedEventCost {
costEditableTextF.text = costToLoad
}
if let gradesToLoad = selectedEventGrade {
gradesEditableTextF.text = gradesToLoad
}
if let docIDtoLoad = selectedEventDocID {
docIDUneditableTextF.text = docIDtoLoad
}
if let eventNameToLoad = selectedEventName {
eventNameEditableTextF.text = eventNameToLoad
}
}
帮助完美加载数据,但是当我尝试从搜索控制器执行 segue 时,数据不存在。
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = selectedEventName
我将 vc 的标题设置为事件名称,并且我最近还添加了一个文本字段来存储它以用于实验目的(this question)。
现在的问题是我想从 Algolia Search Controller 到该 VC 进行数据传输,并且我得到了所有其他字段来显示,除了一个,那就是文档 ID。因此,我创建了一个完成处理函数来获取文档 ID 作为字符串,并在执行 segue 时将其插入到 vc 中,就像实例化 vc 时它的样子一样。
这是功能:
func getTheEventDocID(completion: @escaping ((String?) -> ())) {
documentListener = db.collection(Constants.Firebase.schoolCollectionName).whereField("event_name", isEqualTo: selectedEventName ?? navigationItem.title).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
if let error = error {
print("There was an error fetching the documents: \(error)")
} else {
self.documentsID = querySnapshot!.documents.map { document in
return EventDocID(docID: (document.documentID) as! String)
}
let fixedID = "\(self.documentsID)"
let substrings = fixedID.dropFirst(22).dropLast(3)
let realString = String(substrings)
completion(realString)
}
}
}
当我在数据传输函数中使用该函数时,我认为要么selectedEventName
完成工作并提供价值,我现在将展示:navigationItem.title
//MARK: - Data Transfer From Algolia Search to School Event Details
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
otherVC.getTheEventDocID { (eventdocid) in
if let id = eventdocid {
if segue.identifier == Constants.Segues.fromSearchToSchoolEventDetails {
let vc = segue.destination as! SchoolEventDetailsViewController
vc.selectedEventName = self.nameTheEvent
vc.selectedEventDate = self.dateTheEvent
vc.selectedEventCost = self.costTheEvent
vc.selectedEventGrade = self.gradeTheEvent
vc.selectedEventDocID = id
}
}
}
}
但是当点击搜索结果时它最终什么也没有显示,这非常令人沮丧,我不明白为什么当我在SchoolEventDetailsVC
. 我试图强制展开selectedEventName
,但它崩溃说有一个 nil 值,我不知道为什么。这个问题实际上还有很多,但我只是尽量保持简短,所以人们实际上会尝试阅读它并提供帮助,因为没有人阅读我发布的问题,所以是的,提前谢谢。
解决方案
我有点困惑是什么otherVC
,它在 中设置了自身的属性,而getTheEventDocID
在闭包中设置了 的属性self
,这是一个不同的控制器。但没关系,我希望你知道你在做什么。
由于getTheEventDocID
异步运行,视图将在数据可用之前加载和显示。所以,viewDidLoad
看不到实际的数据,但很快就会过时的东西。
所以,你需要通知细节视图控制器有新数据可用,并刷新它的用户界面。就像是
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
otherVC.getTheEventDocID { (eventdocid) in
if let id = eventdocid {
if segue.identifier == Constants.Segues.fromSearchToSchoolEventDetails {
let vc = segue.destination as! SchoolEventDetailsViewController
vc.selectedEventName = self.nameTheEvent
vc.selectedEventDate = self.dateTheEvent
vc.selectedEventCost = self.costTheEvent
vc.selectedEventGrade = self.gradeTheEvent
vc.selectedEventDocID = id
vc.updateUI()
}
}
}
}
在目标视图控制器中:
class SchoolEventDetailsViewController ... {
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
func updateUI () {
navigationItem.title = selectedEventName
// and so on
}
}
推荐阅读
- python - 如何比较数据框两列中的值
- docusignapi - 文档 | 嵌入式签名 | 发件人如何与收件人/签名者共享“收件人签名 URL”?
- inno-setup - 使用 PrivilegesRequired=admin 从浏览器运行 InnoSetup 安装程序
- sql - 在检查是否需要保留旧值或插入新值时在 postgres SQL 上进行 Upsert 查询?
- java - NavigationComponent 与 BottomNavigationView 项目选择
- javascript - 这样使用flexbox可以吗?
- html - Vue项目中的Bootstrap datepicker显示问题
- javascript - 是否可以将一个功能“分配”给另一个功能?
- javascript - CSSTransition transition-enter-active 事件未按预期工作
- powershell - 将 Azure AD 用户添加到特定的安全组(异常处理)