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

rul*_*ilg 125 ios uicollectionview swift

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

    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
}
Run Code Online (Sandbox Code Playgroud)

有谁知道这个?

控制台上警告的屏幕截图

Con*_*nor 102

您可以通过cell.labelTitle使用if let语句安全地解包来防止崩溃.

if let label = cell.labelTitle{
    label.text = "This is a title"
}
Run Code Online (Sandbox Code Playgroud)

您仍然需要进行一些调试,以了解为什么您在那里获得零值.


Max*_*eod 79

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

我们可以从UITableView.h方法签名看到dequeueReusableCellWithIdentifier返回类型是一个隐式解包可选:

func dequeueReusableCellWithIdentifier(identifier: String!) -> AnyObject! // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
Run Code Online (Sandbox Code Playgroud)

这是由以下感叹号决定的AnyObject:

    AnyObject!
Run Code Online (Sandbox Code Playgroud)

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

Swift编程语言告诉我们:

有时从程序的结构中可以清楚地看出,在首次设置该值之后,可选项将始终具有值.在这些情况下,每次访问时都不需要检查和解包可选的值,因为可以安全地假设它始终具有值.

这些类型的选项被定义为隐式解包的选项.您通过在要使其成为可选的类型之后放置感叹号(String!)而不是问号(String?)来编写隐式展开的可选项.

所以,基本上,某些东西可能在某一点上是零,但从某些角度来看,它永远不会再为零.因此,我们通过将其作为未包装的值来节省一些麻烦.

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

fatal error: unexpectedly found nil while unwrapping an Optional value
Run Code Online (Sandbox Code Playgroud)

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

  • 这是正确的答案,而不是标记的答案. (13认同)

Ron*_*ler 25

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

有关详细信息,请参阅此答案: 为什么UICollectionViewCell的出口无效?

"如果你使用故事板,你不想打电话给它.它将覆盖你的故事板中的内容."


小智 20

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

override func viewDidLoad() {
    super.viewDidLoad()

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

  • 你怎么找> WhateverYourNibName>是? (3认同)

iOS*_*per 13

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


Pru*_*vid 6

当我试图访问时,我收到了他的错误UILabel.我忘了在故事板中连接UILabelIBOutlet那个导致应用程序崩溃的错误!