我的应用程序崩溃,因为它在解开值时会发现nil" header"虽然它没有用,我尝试使用一个保护let语句,是什么方法可以安全地解开这个值呢?
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
self.headerOpen = true
if self.headerOpen == true {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as! HomePageHeader
header.currentUser = self.currentUser
header.usersLocation = self.usersLocation
header.delegate = self
reloadInputViews()
} else if headerOpen == false {
print("header open is false")
}
return header!
}
答案 0 :(得分:0)
if let ...
或guard let ...
可以为您提供帮助。例如:
if let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as? HomePageHeader {
print("header unwrapped")
}
或
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as? HomePageHeader else { print("header not unwrapped") }
print("header unwrapped")
答案 1 :(得分:0)
虽然它没有用,我尝试使用一个守护let语句
由于您使用的是as!
,!
表示该值的强制解包,这会忽略可选类型,如果UICollectionReusableView
没有,您的应用会崩溃符合HomePageHeader
。
您必须使用as?
才能确保安全,就像这样
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as? HomePageHeader else {
return UICollectionReusableView()
}
// do stuff with the header
header.currentUser = self.currentUser
答案 2 :(得分:0)
在 Swift 中,您可以unwrap an optional
使用以下方式之一:
1。使用 !
强行展开optional
值。要使用!
,您必须确保optional
不包含nil
。使用!
有点冒险,因为展开nil
值会导致runtime exception
。
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as! HomePageHeader
在上面的代码中,您强行展开即as! HomePageHeader
。
collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath)
必须返回nil
,然后您将其解包,导致您的应用崩溃。
2。您可以使用 Optional Binding
的另一个选项,即 if let
言。
使用可选绑定来查明可选项是否包含 值,如果是,则使该值可用作临时常量 或变量。可选绑定可与if和while语句一起使用 检查可选内部的值,并提取该值 变成一个常数或变量,作为单一动作的一部分。
在您的代码中,您可以像以下一样使用它:
if let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as? HomePageHeader
{
header.currentUser = self.currentUser
header.usersLocation = self.usersLocation
header.delegate = self
}
Optional Binding
仅适用于optionals
。这就是为什么,我使用as? HomePageHeader
代替as! HomePageHeader
。
3。您还可以使用 guard
语句处理optional
值。
一个保护语句,就像if语句一样,执行语句依赖 在表达式的布尔值上。你使用一个守卫声明 要求条件必须为true才能使代码在。之后 守卫声明将被执行。与if语句不同,是一名警卫 语句总是有一个else子句 - else子句中的代码是 如果条件不成立则执行。
在您的代码中,您可以像以下一样使用它:
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as? HomePageHeader else
{
return
}
header.currentUser = self.currentUser
header.usersLocation = self.usersLocation
header.delegate = self
如果您仍然遇到任何问题,请告诉我。