You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Swift中TableView出现的‘Thread 1: Fatal error: Index out of range’错误

解决UITableView中“Index out of range”崩溃问题

这个崩溃的核心原因很明确:feedImgs数组的元素数量和UITableView实际要渲染的行数不匹配,或者当前的indexPath.row超出了feedImgs的合法下标范围。咱们一步步来修复:

第一步:确保数据源的一致性

先检查你的UITableView代理方法numberOfRowsInSection,它返回的行数必须和feedImgs.count完全对齐。你代码里同时用到了myFeed和feedImgs两个数组,如果numberOfRowsInSection返回的是myFeed.count,但feedImgs的长度比它小,必然会触发越界错误。

正确的行数配置应该是这样:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // 要么返回feedImgs的长度,要么确保myFeed和feedImgs的元素数量完全一致
    return feedImgs.count
}

第二步:安全访问数组元素

别再直接用feedImgs[indexPath.row]这种强制下标访问了,先做范围校验,用可选绑定规避崩溃风险。比如获取图片URL的部分可以改成:

// 先校验下标合法性,再安全解析URL
guard indexPath.row < feedImgs.count, 
      let imgUrlString = feedImgs[indexPath.row] as? String,
      let url = URL(string: imgUrlString) else {
    // 不符合条件时,返回带占位图的cell或者做其他兜底处理
    cell.imageView?.image = UIImage(named: "placeholder")
    return cell
}

第三步:替换所有不安全的强制解包

你代码里的!强制解包(比如url!、data!、image!)都是潜在的崩溃炸弹,必须换成安全的处理方式。另外,同步加载网络图片(NSData(contentsOf:url!))会严重阻塞主线程,导致界面卡顿甚至无响应,一定要改成异步加载:

// 用URLSession异步加载图片,避免阻塞主线程
URLSession.shared.dataTask(with: url) { [weak self, weak cell] data, _, error in
    guard let self = self, let data = data, error == nil, let cell = cell else { return }
    DispatchQueue.main.async {
        var image = UIImage(data: data)
        // 调整图片大小前先校验原图是否有效
        if let originalImage = image {
            image = self.resizeImage(image: originalImage, toTheSize: CGSize(width: 80, height: 80))
            cell.imageView?.image = image
            // 安全设置圆角
            if let cellImageLayer = cell.imageView?.layer {
                cellImageLayer.cornerRadius = 35
                cellImageLayer.masksToBounds = true
            }
        } else {
            // 图片解析失败时显示占位图
            cell.imageView?.image = UIImage(named: "placeholder")
        }
    }
}.resume()

完整优化后的代码片段

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    
    // 配置文本标签样式
    cell.textLabel?.backgroundColor = .clear
    cell.detailTextLabel?.backgroundColor = .clear
    cell.textLabel?.textColor = .white
    cell.textLabel?.numberOfLines = 0
    cell.textLabel?.lineBreakMode = .byWordWrapping
    cell.detailTextLabel?.textColor = .white
    
    // 设置交替行背景色
    cell.backgroundColor = indexPath.row % 2 == 0 ? UIColor(white: 1, alpha: 0.1) : UIColor(white: 1, alpha: 0.2)
    
    // 安全加载标题和日期
    if indexPath.row < myFeed.count {
        let feedItem = myFeed.object(at: indexPath.row) as? [String: Any]
        cell.textLabel?.text = feedItem?["title"] as? String
        cell.detailTextLabel?.text = feedItem?["pubDate"] as? String
    }
    
    // 安全加载并配置图片
    guard indexPath.row < feedImgs.count, 
          let imgUrlString = feedImgs[indexPath.row] as? String,
          let url = URL(string: imgUrlString) else {
        cell.imageView?.image = UIImage(named: "placeholder")
        return cell
    }
    
    URLSession.shared.dataTask(with: url) { [weak self, weak cell] data, _, error in
        guard let self = self, let data = data, error == nil, let cell = cell else { return }
        DispatchQueue.main.async {
            var image = UIImage(data: data)
            if let originalImage = image {
                image = self.resizeImage(image: originalImage, toTheSize: CGSize(width: 80, height: 80))
                cell.imageView?.image = image
                if let cellImageLayer = cell.imageView?.layer {
                    cellImageLayer.cornerRadius = 35
                    cellImageLayer.masksToBounds = true
                }
            } else {
                cell.imageView?.image = UIImage(named: "placeholder")
            }
        }
    }.resume()
    
    return cell
}

内容的提问来源于stack exchange,提问作者Kadio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:29:53