iOS Swift中Table View图片加载失败及崩溃问题求助
问题解决方案
一、崩溃原因及修复
崩溃触发点在URL(string: doctorData[indexPath.row].picture ?? "")!的强制解包:
- 当
doctor.picture为nil时,你用?? ""替换为空字符串,URL(string: "")会返回nil,此时强制解包!直接引发崩溃。 - 即便
doctor.picture有值,也可能因格式不合法导致URL创建失败,强制解包同样会崩溃。
修复代码:
用guard let安全解析URL,跳过无效链接:
guard let picUrlStr = doctor.picture, let picUrl = URL(string: picUrlStr) else { // 链接无效时设置占位图或空 cell.doctorimg.image = UIImage(named: "placeholder") return cell }
二、主线程阻塞问题及修复
Data(contentsOf:)是同步网络请求方法,在主线程执行会阻塞UI,导致列表滚动卡顿甚至无响应,必须改用异步请求方案。
1. 先给自定义cell添加请求管理属性
在DoctorTableViewcellTableViewCell类中新增代码:
var imageTask: URLSessionDataTask? override func prepareForReuse() { super.prepareForReuse() // 复用前取消未完成的图片请求,清空旧图片 imageTask?.cancel() doctorimg.image = UIImage(named: "placeholder") }
2. 修改cellForRowAt中的图片加载逻辑
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = doctorsTableView.dequeueReusableCell(withIdentifier: "DoctorTableViewcellTableViewCell", for: indexPath) as! DoctorTableViewcellTableViewCell let doctor = doctorData[indexPath.row] cell.doctorname.text = doctor.name cell.doctorDepartment.text = doctor.department cell.doctorspeclization.text = doctor.specialization cell.hospitalName.text = doctor.hospital // 安全解析图片URL guard let picUrlStr = doctor.picture, let picUrl = URL(string: picUrlStr) else { cell.doctorimg.image = UIImage(named: "placeholder") return cell } // 异步加载图片 cell.imageTask = URLSession.shared.dataTask(with: picUrl) { data, response, error in guard let imageData = data, error == nil else { // 加载失败,切回主线程设置占位图 DispatchQueue.main.async { cell.doctorimg.image = UIImage(named: "placeholder") } return } // 加载成功,切回主线程更新UI DispatchQueue.main.async { cell.doctorimg.image = UIImage(data: imageData) } } // 启动请求 cell.imageTask?.resume() return cell }
额外优化建议
- 添加占位图:图片加载完成前显示占位图,提升用户体验。
- 图片缓存:可自行实现内存/磁盘缓存逻辑,或使用成熟第三方库(如Kingfisher、SDWebImage)简化图片加载与缓存,避免重复请求相同资源。
内容的提问来源于stack exchange,提问作者Nimish Mothghare
相关产品推荐
相关产品推荐

