Использование группы отправки в методе делегирования TableView(_ TableView:, cellForRowAt indexPath:); «Выражение типа UITableViewCell не используется»

#ios #swift #uitableview #uikit

#iOS #swift #uitableview #uikit

Вопрос:

Я пытаюсь вызвать асинхронную функцию (соблюдая значение базы данных Firebase) и использовать диспетчерскую группу для уведомления о том, когда данные были извлечены из указанной асинхронной функции.

Это происходит в моем TableView (_ TableView:, cellForRowAt indexPath:) Метод UITableViewDelegate. Сначала я объявляю «cell» как пользовательский подкласс UITableViewCell (в данном случае, «CommentCell»). Затем я создаю группу отправки, вхожу в группу, извлекаю данные из firebase, использую указанные данные для заполнения моей ячейки, а затем оставляю / уведомляю группу отправки. Когда группа получает уведомление, я просто хочу вернуть свою ячейку.

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

Выражение типа ‘CommentCell?’ не используется

Вот мой метод делегирования TableView(_ TableView:, cellForRowAt indexPath:):

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    var cell: CommentCell!

    let group = DispatchGroup()

    group.enter()
    Database.database().reference().child("Users/(comments[indexPath.row].uid)").observeSingleEvent(of: .value) { (snapshot) in
        let data = snapshot.value as! [String:Any]
        cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CommentCell
        cell.parentVC = self
        cell.uid = self.comments[indexPath.row].uid
        cell.photoUrl = data["photoUrl"] as? String
        cell.imageView?.image = UIImage(named: "profile")?.resize(targetSize: CGSize(width: 35, height: 35))
        cell.imageView?.layer.cornerRadius = 17.5
        self.loadImage(string: cell.photoUrl, cell: cell)
        cell.imageView?.clipsToBounds = true
        cell.textLabel?.text = data["name"] as? String
        cell.textLabel?.font = .boldSystemFont(ofSize: 15)
        cell.textLabel?.numberOfLines = 0
        cell.detailTextLabel?.textColor = .darkGray
        cell.detailTextLabel?.font = .systemFont(ofSize: 14)
        cell.detailTextLabel?.text = self.comments[indexPath.row].text
        cell.detailTextLabel?.numberOfLines = 0
        cell.selectionStyle = .none
        group.leave()
    }

    group.notify(queue: .main) {
        return cell
    }
}
  

Прилагается изображение кода и ошибок.

введите описание изображения здесь

Комментарии:

1. Вы не можете пытаться вернуть ячейку асинхронно. Это не сработает.

2. Пожалуйста, выполните поиск, прежде чем задавать запрос. Вопрос о том, как заполнить таблицу загруженными данными, обсуждался здесь много, много раз.

Ответ №1:

Прежде всего, в tableView(_:,cellForRowAt:) вы должны возвращать ячейку синхронно / немедленно. Это не то место, где вы можете ждать загрузки содержимого из сети или файловой системы, поскольку это заблокировало бы пользовательский интерфейс. Для асинхронной загрузки данных выполните что-то подобное следующему:

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

Возвращаясь к вашему коду, в вашей функции нет wait() вызова, следовательно, поток управления будет просто выполняться до конца функции и никогда не завершится возвратом ( notify функция не будет блокироваться!). Вот почему вы получаете сообщение об ошибке.