Swift 3: ошибка выхода индекса за пределы диапазона

#ios #swift3

#iOS #swift3

Вопрос:

Я новичок в iOS. Выполнение проекта путем просмотра руководства, написанного с использованием Swift 2.
Это работает, когда автор запускает приложение, но не в моем случае.

ViewController:

 var books = [[String: AnyObject]]()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    searchBar.delegate = self
}
 

И расширение

 extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath)

        // error on this line
        if let volumeInfo = self.books[indexPath.row]["volumeInfo"] as? [String: AnyObject] {
            cell.textLabel?.text = volumeInfo["title"] as? String
            cell.detailTextLabel?.text = volumeInfo["subtitle"] as? String
        }

        return cell
    }
}
 

Вывод консоли:

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

Пожалуйста, помогите мне определить, в чем причина.

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

1. Сомневаюсь, что это имеет какое-либо отношение к Swift 3 против 2. Ваш books массив, вероятно, пуст (или, по крайней мере indexPath.section >= books.count ,). Проверьте, что находится внутри indexPath и books , и убедитесь, что вы не пропустили часть кода, в которой books инициализируется массив.

2. Что вы возвращаете numberOfRowsInSection ? Очевидно, books что массив пуст.

Ответ №1:

Вы должны возвращать books.count из numberOfRowsInSection , никогда не «жестко кодировать» это значение, если оно связано с массивом источников данных.

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return books.count
}
 

PS: В Swift 3 вы должны использовать [String:Any] , а не [String:AnyObject]

Ответ №2:

Я многое предполагаю о вашем проекте, но если у вас есть только один раздел в вашем TableView, который используется по умолчанию, вам не следует использовать indexPath.section для вашего словаря books. Вы должны использовать indexPath.row, как показано ниже

Изменить —

 if let volumeInfo = self.books[indexPath.section]["volumeInfo"] as? [String: AnyObject]
 

Для —

 if let volumeInfo = self.books[indexPath.row]["volumeInfo"] as? [String: AnyObject] {
 

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

1. О, извините: ( Это была одна из попыток решить проблему. На самом деле это .row. Еще раз извините

2. Это все равно не должно привести к сбою, поскольку в них должно быть по крайней мере столько строк, сколько разделов.

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

4. Спасибо вам за вашу помощь. Вы дали мне общее представление о разделах и строках

5. В какой момент вы получаете сообщение об ошибке? Когда вы запускаете приложение? Кроме того, вы когда-нибудь добавляли какие-либо объекты в свой книжный словарь?