#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
функция не будет блокироваться!). Вот почему вы получаете сообщение об ошибке.