it-roy-ru.com

Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательных значений

Я использовал 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
}

Кто-нибудь знает об этом?

 Screenshot for warning on Console

120
rulilg

Почти наверняка ваш идентификатор повторного использования "title" неверен.

Из сигнатуры метода UITableView.hdequeueReusableCellWithIdentifier можно видеть, что тип возвращаемого значения - неявно развернутый необязательный:

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

Это определяется восклицательным знаком после AnyObject:

    AnyObject!

Итак, первое, что нужно рассмотреть, что такое «Неявно развернутый необязательный»?

Язык программирования Swift говорит нам:

Иногда из структуры программы ясно, что необязательный будет всегда иметь значение, после того, как это значение впервые установлено. В этих случаях это Это полезно для устранения необходимости проверять и разворачивать значение необязательного значения каждый раз, когда к нему обращаются, потому что можно с уверенностью предположить, что он имеет ценить все время.

Эти типы опций определены как неявно развернутые ДОПОЛНИТЕЛЬНО. Вы пишете неявно развернутый необязательный, помещая восклицательный знак (строка!) вместо знака вопроса (строка?) после тип, который вы хотите сделать необязательным.

Так что, по сути, что-то, что могло бы быть нулевым в какой-то момент, но что в какой-то момент больше никогда не будет ноль. Поэтому мы избавляем себя от некоторого беспокойства, принимая это за развернутое значение.

В этом случае имеет смысл для dequeueReusableCellWithIdentifier возвращать такое значение. Предоставленный идентификатор должен быть уже использован для регистрации ячейки для повторного использования. Укажите неверный идентификатор, очередь не может его найти, а среда выполнения возвращает ноль, который никогда не должен происходить. Это фатальная ошибка, приложение вылетает, и вывод консоли выдает:

fatal error: unexpectedly found nil while unwrapping an Optional value

Итог: проверьте идентификатор повторного использования вашей ячейки, указанный в .storyboard, Xib или в коде, и убедитесь, что он корректен при снятии очереди. 

78
Max MacLeod

Вы можете предотвратить сбой, безопасно развернув cell.labelTitle с помощью оператора if let

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

Вам все равно придется выполнить некоторую отладку, чтобы понять, почему вы получаете нулевое значение.

101
Connor

Проверьте, регистрируется ли ячейка с self.collectionView.registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String). Если так, то удалите эту строку кода.

См. Этот ответ для получения дополнительной информации: Почему выход UICollectionViewCell равен нулю?

«Если вы используете раскадровку, вы не хотите называть это. Она перезапишет то, что у вас есть в раскадровке».

25
Ron Fessler

Я не знаю, это ошибка или что-то в этом роде, но ваши ярлыки и другие пользовательские интерфейсы не инициализируются автоматически при использовании пользовательской ячейки. Вы должны попробовать это в вашем классе UICollectionViewController. Это сработало для меня.

override func viewDidLoad() {
    super.viewDidLoad()

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

Заменить эту строку cell.labelTitle.text = "This is a title"
с cell.labelTitle?.text = "This is a title" 

12
iOS Developer

Я получил его ошибку, когда пытался получить доступ к UILabel. Я забыл подключить UILabel к IBOutlet в раскадровке, и это приводило к падению приложения с этой ошибкой !!

6
Pruthvid

У меня была эта проблема, и проблема была в контроллерах представления. Я не уверен, как ваше приложение структурировано, поэтому я просто объясню, что я нашел. Я довольно новичок в xcode и coding, так что терпите меня.

Я пытался программно изменить текст на UILabel. Использование «self.mylabel.text» работало нормально, пока я не добавил еще один контроллер представления под тот же класс, который также не включал эту метку. Именно тогда я получил ошибку, которую вы видите. Когда я добавил тот же UILabel и подключил его к этому дополнительному контроллеру представления, ошибка исчезла.

Короче говоря, кажется, что в Swift все контроллеры представлений, назначенные одному и тому же классу, должны ссылаться на код, который у вас там, иначе вы получите ошибку. Если у вас два разных контроллера представления с разным кодом, присвойте их разным классам. Это сработало для меня и, надеюсь, относится к тому, что вы делаете.

3
ClareHuxtable

фатальная ошибка: неожиданно найден ноль при развертывании необязательного значения

  1. Проверьте коллекцию IBOutlet, потому что эта ошибка будет иметь шанс несвязанного использования объекта uielement. 

:) надеется, что это поможет некоторым борющимся людям. 

2
Kishore Kumar

У меня была такая же проблема на Xcode 7.3. Мое решение состояло в том, чтобы убедиться, что мои ячейки имели правильные идентификаторы reuse. В разделе табличного представления установите в ячейке табличного представления соответствующее имя идентификатора, которое вы используете в программе, убедитесь, что они совпадают

1
ekeith

Также можно использовать оператор Nil Coalescing.

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

Я сам искал решение этой проблемы. только моя проблема была связана с UITableViewCell, а не 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. так что мне просто пришлось сменить стиль ячейки в раскадровке, и все было хорошо. 

Я догадываюсь, что твой лейбл всегда должен быть там?

Так что, если ваш следующий совет Коннора, который в основном означает, ЕСЛИ этот ярлык доступен, то используйте его. Если ваш стиль настроен правильно и идентификатор повторного использования соответствует идентификатору, установленному в раскадровке, вам не нужно делать эту проверку, если вы не используете более одной пользовательской ячейки.

1
Christer

То же самое сообщение здесь, но с другой причиной. У меня была UIBarButton, которая подтолкнула переход. У segue не было идентификатора.

0
David DelMonte

У меня была та же проблема, и причина была в том, что я пытался загрузить UIImage с неправильным именем. Дважды проверьте .setImage(UIImage(named: "-name-" звонков и убедитесь, что имя правильно.

0
Hugo Sequeira