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

如何在UITableView单元格中重新加载SDWebImage异步加载的UIImage

解决SDWebImage在UITableView中异步加载图片不及时刷新的问题

核心问题分析

你原代码的错误在于使用了全局的itemImage对象加载图片,再将其赋值给cell的imageView。这种做法完全违背了UITableView的cell复用机制:

  • 异步加载图片时,cell已经被返回并显示,itemImage的后续更新无法同步到对应的cell;
  • 直接赋值cell.imageView?.image = itemImage.image时,异步请求还未完成,只能拿到占位图,只有当cell被复用重新执行cellForRowAt时,才可能读取到缓存的图片。

正确解决方案

直接使用cell自带的imageView调用SDWebImage的sd_setImage方法,SDWebImage内部已经处理了异步加载完成后的UI更新,以及cell复用场景下的图片匹配问题,无需手动调用表格刷新:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let item = items[indexPath.row]
    
    // 直接操作cell的imageView,无需全局变量
    if let url = URL(string: item.stringUrl) {
        let placeholderImage = UIImage(named: "noPhoto.png")
        cell.imageView?.sd_setImage(with: url, placeholderImage: placeholderImage)
    } else {
        // URL无效时,手动设置占位图
        cell.imageView?.image = UIImage(named: "noPhoto.png")
    }

    cell.textLabel?.text = item.title
    cell.detailTextLabel?.text = "item id: \(item.id)"
    return cell
}

为什么之前的尝试无效

  • 调用reloadData():每次图片加载完成都刷新整个表格,不仅性能损耗大,还会强制表格回到顶部,完全破坏滚动体验;
  • 调用reloadRows(at:):异步加载完成后,原indexPath对应的cell可能已经被复用给其他行,此时刷新原indexPath会触发cell重新初始化,加上SDWebImage的缓存状态未同步,就会出现图片随机显示或隐藏的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:27:23