Ошибка индекса вне диапазона, даже если количество значений соответствует количеству строк - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь установить для некоторых изображений представления изображений в виде таблицы, и у меня установлено число строк return keys.count, которое после печати подтверждается равным 5, что идеально.

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "stockCell", for: indexPath) as! StockCell

        let stock = stockData[keys[indexPath.row]]!

        var images = [String]()
        stock.news.forEach { images.append($0.image) }
        print("\n\nNumber of Images: \(images.count)\n\n\n")

        if let companyImageUrl = URL(string: images[indexPath.row]) {
            ImageService.getImage(url: companyImageUrl) { (image) in
                cell.companyLogoImageView.image = image
            }
        }

        return cell
    }
}

Я поместил туда оператор print, чтобы вывести images.count (должно быть 5), но консоль показывает 2, затем 5 (x3), затем снова 2 - это вызывает ошибку индекса вне диапазона, предположительно, он видит 2, когда должно быть 5:

enter image description here

Почему images.count показывает 2 в первом и последнем точках, но 5 в остальных?

РЕДАКТИРОВАТЬ: Остальной код

Получение данных (в viewDidLoad):

    fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
        switch result {
        case .success(let object):
            self.stockData = object
            self.keys = Array(object.keys)
        print("stockData: \n\n\(self.stockData)")
        case .failure(let error):
            print("Error decoding JSON: \n\n\(error)")
        }
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }

Для данных задан словарь с отдельным массивом ключей:

var stockData = [String:Stock]()
var keys = [String]()

Структуры для декодирования JSON:

struct Welcome: Decodable {
    let aapl, fb, msft, tsla, goog: Stock

    enum CodingKeys: String, CodingKey {
        case aapl = "AAPL"
        case fb = "FB"
        case msft = "MSFT"
        case tsla = "TSLA"
        case goog = "GOOG"
    }
}

struct Stock: Decodable {
    let quote: Quote
    let news: [News]
}

struct Quote: Decodable {
    let symbol: String
    let companyName: String
    let latestPrice: Double
}

struct News: Decodable {
    let url: String
    let image: String
}

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Вы предполагаете, что у вас есть 5 изображений, потому что keys.count равно 5, и это неправильно, поскольку keys.count говорит вам, что у вас есть 5 акций в словаре, который вы создали из сообщения json.

Теперь к каждой акции прикреплен массив новостей, который, как я полагаю, содержит новостные статьи / сообщения, относящиеся к акции за один день или что-то подобное, поэтому этот массив может содержать от 0 до бесконечного (маловероятного) количества статей новостей. , (в этом случае количество статей варьируется от 2 до 5).

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

Так что этот код нужно изменить, но я не уверен, как

if let companyImageUrl = URL(string: images[indexPath.row]) {
        ImageService.getImage(url: companyImageUrl) { (image) in
            cell.companyLogoImageView.image = image
        }
}

Будете ли вы показывать все изображения? тогда вам нужно каким-то образом окружить это циклом, но у меня возникает ощущение, что вы хотите показать только одно изображение, так что, возможно, измените URL(string: images[indexPath.row]) на URL(string: images[0])

0 голосов
/ 16 ноября 2018

Добавьте еще один отпечаток и убедитесь, что количество новостей также отличается для каждой строки. Затем выясните, почему это не так.

stock.news.forEach { images.append($0.image) }
print("\n\nNumber of Images: \(images.count)\n\n\n")
print("\n\nNumber of stock.news: \(stock.news.count)\n\n\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...