当我创建一个新的NSVC子类并向其添加一些IBOulets时,当我尝试访问它们时它们总是为零。我尝试创建一个新项目,只有一个VC类,只有一个Outlet,它仍然是零。
我已经检查过它们确实是连接的。我尝试用完整的笔尖名称实例化该类。我还清理了项目,并删除了派生数据。没有任何区别。
那么可能导致这种情况呢?它正在讨论所有新项目;我为我的旧项目添加了新的插座,它们工作正常。所有的IBOutlets都是零,而不仅仅是少数几个。我在Xcode 7.1.1上。
我得到的错误是:
致命错误:在解包可选值时意外发现nil
答案 0 :(得分:1)
如果其他人遇到类似的问题,我找到了解决方法。 IBOutlet是零,因为它的超级视图从未加载过,因此应用程序从未创建它。一个简单的黑客就是在使用任何子视图之前写这个:
let view = viewController.view
这会创建视图,因此它上面有所有插座。
P.S。我知道这不是一个真正的解决方案,但我想不出另一个。如果有人有任何建议,请随时发布。
答案 1 :(得分:0)
我的猜测是,您尝试在加载视图之前尝试访问init方法中的outlet,或者在设置值时从访问器访问。处理这种情况有两种方法。
第一种是推迟更新子视图,直到您知道视图已加载为止。我通过从updateView()
调用viewWillAppear()
方法来完成此操作。我通常在变量变化时调用此方法,因此我测试以确保在继续之前视图已加载。如果视图尚不存在,则设置视图没有任何价值。它看起来像这样:
class MyViewController: UIViewController {
var product: Product {
didSet {
updateView()
}
}
@IBOutlet private weak var productNameLabel: UILabel!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
updateView()
}
private func updateView() {
guard isViewLoaded() else {
return
}
if let product = product {
productNameLabel.text = product.title
}
}
}
另一个与您正在执行的操作类似的选项是强制视图提前加载。我认为这不太可取,但在某些情况下,这是正确的方法。但不是按照你发现的方式去做,而是更有意地这样做:
class MyViewController: UIViewController {
var product: Product {
didSet {
loadViewIfNeeded()
productNameLabel.text = product.title
}
}
@IBOutlet private weak var productNameLabel: UILabel!
}