如何安全地展开标题值

时间:2018-03-25 10:39:15

标签: swift collections view

我的应用程序崩溃,因为它在解开值时会发现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!

}

3 个答案:

答案 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

如果您仍然遇到任何问题,请告诉我。