致命错误:在解包可选值时意外发现nil

时间:2014-07-09 00:12:34

标签: ios swift uicollectionview

我在Swift中使用UICollectionView但是当我尝试更改单元格标签的文本时,我得到了。

    func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int
{
    return 5
}

func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
    var cell = collectionView.dequeueReusableCellWithReuseIdentifier("title", forIndexPath: indexPath) as TitleCollectionViewCell
    // Next line: fatal error: unexpectedly found nil while unwrapping an Optional value
    cell.labelTitle.text = "This is a title"
    return cell
}

有人知道吗?

Screenshot for warning on Console

13 个答案:

答案 0 :(得分:101)

您可以使用cell.labelTitle语句安全地展开if let,以防止崩溃发生。

if let label = cell.labelTitle{
    label.text = "This is a title"
}

你仍然需要做一些调试,看看为什么你会得到一个零值。

答案 1 :(得分:79)

几乎可以肯定,您的重用标识符"title"不正确。

我们可以从UITableView.h的{​​{1}}方法签名中看到,返回类型为 隐式解包可选

dequeueReusableCellWithIdentifier

这是由func dequeueReusableCellWithIdentifier(identifier: String!) -> AnyObject! // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one. 之后的感叹号决定的:

AnyObject

所以,首先要考虑的是,什么是“隐式解包可选”?

The Swift Programming Language告诉我们:

  

有时从程序的结构中可以明确看出一个可选的意愿   在首次设置该值之后,始终有一个值。在这些情况下,它   有助于删除检查和解包可选值的需要   每次访问它,因为它可以安全地假设有一个   一直都很重要。

     

这些类型的选项被定义为隐式展开   选配。你通过放置一个隐式解包的可选项来编写   感叹号(String!)而不是问号(String?)之后   您想要选择的类型。

所以,基本上,某些事情可能在某一点上是零,但从某些角度来看,它永远不会再为零。因此,我们把它作为未包装的价值来节省一些麻烦。

在这种情况下, AnyObject! 返回这样的值是有意义的。提供的标识符必须已用于注册单元以供重用。提供错误的标识符,dequeue找不到它,运行时返回一个永远不会发生的nil。这是一个致命错误,应用程序崩溃,控制台输出提供:

dequeueReusableCellWithIdentifier

底线:检查.storyboard,Xib或代码中指定的单元格重用标识符,并确保在出列时它是正确的。

答案 2 :(得分:25)

检查单元格是否在self.collectionView.registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String)注册。如果是,则删除该行代码。

有关详细信息,请参阅此答案: Why is UICollectionViewCell's outlet nil?

“如果你正在使用故事板,你不想打电话给它。它会覆盖你在故事板中的内容。”

答案 3 :(得分:20)

我不知道它是错误还是其他什么,但是当您使用自定义单元格时,您的标签和其他UI不会自动初始化。你应该在你的UICollectionViewController课程中试试这个。它对我有用。

override func viewDidLoad() {
    super.viewDidLoad()

    let nib = UINib(nibName: "<WhateverYourNibName>", bundle: nil)
    self.collectionView.registerNib(nib, forCellReuseIdentifier: "title")
}

答案 4 :(得分:12)

替换此行  cell.labelTitle.text = "This is a title"
 同 cell.labelTitle?.text = "This is a title"

答案 5 :(得分:6)

我在尝试访问UILabel时遇到了错误。我忘了在Storyboard中将UILabel连接到IBOutlet,这导致应用程序因此错误而崩溃!!

答案 6 :(得分:3)

我也遇到了这个问题,问题出在视图控制器中。我不确定你的应用程序是如何构建的,所以我只会解释我发现的内容。我对xcode和编码很新,所以请耐心等待。

我试图以编程方式更改UILabel上的文本。使用“self.mylabel.text”工作正常,直到我在同一个类下添加了另一个视图控制器,但不包含该标签。那是我收到你所看到的错误的时候。当我添加相同的UILabel并将其连接到另外的视图控制器时,错误就消失了。

简而言之,似乎在Swift中,分配给同一个类的所有视图控制器都必须引用你在那里的代码,否则你会收到错误。如果您有两个具有不同代码的不同视图控制器,请将它们分配给不同的类。这对我有用,并希望适用于你正在做的事情。

答案 7 :(得分:2)

  

致命错误:在解包可选值时意外发现nil

  1. 检查IBOutlet集合,因为此错误将有机会取消连接的uielement对象使用情况。
  2. :)希望它能帮助一些挣扎的人。

答案 8 :(得分:1)

我自己寻找解决方案。只有我的问题与你在这里提到的UITableViewCell Not UICollectionView有关。

首先,我是iOS开发的新手。就像全新的,坐在这里试图通过我的第一个教程,所以不要接受我的任何事情。 (除非它的工作;))

我得到cell.detailTextLabel.text的零引用 - 重新阅读我关注的教程视频后,看起来我没有错过任何东西。所以我输入了UITableViewCell的头文件并找到了这个。

var detailTextLabel: UILabel! { get } // default is nil. label will be created if necessary (and the current style supports a detail label).

所以我注意到它(并且当前样式支持细节标签) - 嗯,默认情况下,自定义样式没有detailLabel。所以我只需要在故事板中切换单元格的样式,一切都很好。

我猜你的标签应该永远在那里?

因此,如果你的以下康纳的建议,这基本上意味着,如果该标签可用,那么使用它。如果您的样式设置正确且重用标识符与故事板中设置的样式匹配,则除非您使用多个自定义单元格,否则不应进行此检查。

答案 9 :(得分:1)

也可以使用Nil Coalescing Operator。

rowName = rowName != nil ?rowName!.stringFromCamelCase():""

答案 10 :(得分:1)

我在Xcode 7.3上遇到了同样的问题。我的解决方案是确保我的单元格具有正确的重用标识符。在表格视图部分下,将表格视图单元格设置为您在程序中使用的相应标识符名称,确保它们匹配

答案 11 :(得分:0)

我遇到了同样的问题,原因是因为我试图用错误的名称加载UIImage。仔细检查.setImage(UIImage(named: "-name-"次来电并确保名称正确无误。

答案 12 :(得分:0)

此处有相同的消息,但原因不同。我有UIBarButton推了一个segue。 segue缺少标识符。