为什么我的应用"Unexpectedly found nil"崩溃?



我试图添加一个标签的图片,这将表明多少时间选择的图片显示。我给包含图片的detailView添加了一个标签,并将标签链接到DetailViewController类。我已经为这个标签设置了一个名称,但是我得到了"意外发现nil"。从列表中选择图片时崩溃。这是一个DetailViewController:

class DetailViewController: UIViewController {
@IBOutlet var imageView: UIImageView!
@IBOutlet var name: UILabel!

var selectedImage : String?
var detailVCTitle: String?

override func viewDidLoad() {
super.viewDidLoad()
title = detailVCTitle
navigationItem.largeTitleDisplayMode = .never
if let imageToLoad = selectedImage {
imageView.image = UIImage(named: imageToLoad)
}
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.hidesBarsOnTap = true
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.hidesBarsOnTap = false
}

}

这是一个我想修改的函数:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as?
DetailViewController {
counter += 1
vc.selectedImage = pictures[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
vc.detailVCTitle = "Picture (indexPath.row + 1) of (pictures.count)"
vc.name.text = "It was shown (counter) times"
}
}

简短而明显的答案是vc.namenil,并且它是隐式解包装的可选项。

问题是"为什么是nil?,假设其他一切都是正确的,并且您已经连接了出口?

原因是视图在加载时被实例化并分配给outlet属性。当loadView被显式调用时,或者当有对视图控制器的view属性的引用时,它会隐式地发生。在输入vc.name.text=...之前,这两种情况都没有发生,所以会得到nil崩溃。

直接从另一个对象引用视图控制器的视图违反了封装;它将你的表视图控制器与细节视图控制器的实现细节紧密耦合。

你会注意到你的其他属性,selectedImagedetailVCTitle只是;简单的属性。视图控制器在viewDidLoad中对它们做了一些事情。

你应该对你的count做同样的事情:

class DetailViewController: UIViewController {
@IBOutlet var imageView: UIImageView!
@IBOutlet var name: UILabel!

var selectedImage : String?
var detailVCTitle: String?
var counter = 0

override func viewDidLoad() {
super.viewDidLoad()
title = detailVCTitle
navigationItem.largeTitleDisplayMode = .never
if let imageToLoad = selectedImage {
imageView.image = UIImage(named: imageToLoad)
}
name.text = "It was shown (counter) times"
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as?
DetailViewController {
counter += 1
vc.selectedImage = pictures[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
vc.detailVCTitle = "Picture (indexPath.row + 1) of (pictures.count)"
vc.counter = counter
}
}

现在,你的表视图只知道你的细节视图需要一个计数器。它不知道,也不需要知道,这个计数器是如何使用的。你的细节视图控制器可以在多个地方或以不同的方式使用它,这取决于它的值或其他…

相关内容

最新更新