如何解决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
相关产品推荐
相关产品推荐

