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

UITableView垂直滚动卡顿求助:SDWebImage回调中处理圆角图片所致

UITableView滚动卡顿优化:图片圆角处理方案

问题描述

在UITableViewCell中使用SDWebImage下载图片,下载完成的回调block内调用自定义circularImage方法处理圆角,导致UITableView垂直滚动时出现卡顿。请问是否需要通过GCD调度解决该问题以实现流畅滚动?

相关代码

自定义圆角处理方法:

func circularImage(size: CGSize?) -> UIImage? {
    let newSize = size ?? self.size
    
    let minEdge = min(newSize.height, newSize.width)
    let size = CGSize(width: minEdge, height: minEdge)
    
    UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
    let context = UIGraphicsGetCurrentContext()
    
    self.draw(in: CGRect(origin: CGPoint.zero, size: size), blendMode: .copy, alpha: 1.0)
    
    context?.setBlendMode(.copy)
    context?.setFillColor(UIColor.clear.cgColor)
    
    let rectPath = UIBezierPath(rect: CGRect(origin: CGPoint.zero, size: size))
    let circlePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: size))
    rectPath.append(circlePath)
    rectPath.usesEvenOddFillRule = true
    rectPath.fill()
    
    let result = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return result
}

UITableViewCell内代码:

if let thumbImageUrlUW = valueUW.thumbImageUrl {
    UIImageView().sd_setImage(with: URL(string: thumbImageUrlUW)) { (thumbImage, _, _, _) in
        if let thumbImageUW = thumbImage, let roundedThumbImage = thumbImageUW.circularImage(size: imageSize) {
            valueUW.thumbImage = roundedThumbImage
            colorsUW.remove(at: index)
            colorsUW.insert(valueUW, at: index)
        }
    }
}

界面截图

ProductDetailsInsideTableViewCell
UIAction with details


问题分析

卡顿的核心原因是图片圆角处理操作在主线程执行:circularImage方法中的图形绘制(如UIGraphicsBeginImageContextWithOptions、路径绘制等)属于CPU密集型操作,会阻塞主线程的UI刷新,导致UITableView滚动时掉帧卡顿。


优化方案

1. 用GCD将图片处理移到后台线程

SDWebImage的默认回调在主线程执行,需要把circularImage的调用放到后台队列,处理完成后切回主线程更新UI和数据,避免阻塞主线程。

修改后的Cell代码:

if let thumbImageUrlUW = valueUW.thumbImageUrl {
    UIImageView().sd_setImage(with: URL(string: thumbImageUrlUW)) { (thumbImage, _, _, _) in
        guard let thumbImageUW = thumbImage else { return }
        // 后台线程执行图片圆角处理
        DispatchQueue.global().async {
            if let roundedThumbImage = thumbImageUW.circularImage(size: imageSize) {
                // 切回主线程更新数据和UI
                DispatchQueue.main.async {
                    valueUW.thumbImage = roundedThumbImage
                    // 直接修改数据源对应项,无需remove+insert
                    colorsUW[index] = valueUW
                    // 刷新对应cell,保证UI同步
                    self.tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
                }
            }
        }
    }
}

2. 更高效的圆角处理替代方案

自定义图形绘制的效率并非最优,推荐以下两种更适合UITableView场景的方案:

方案A:使用SDWebImage自带的图片处理器

SDWebImage内置SDImageRoundCornerTransformer,可以在下载阶段直接处理圆角,内部已做好线程优化,无需自己编写绘制代码:

// 创建圆形图片处理器(圆角半径设为图片边长的一半)
let transformer = SDImageRoundCornerTransformer(
    cornerRadius: imageSize.width / 2,
    corners: .allCorners,
    borderWidth: 0,
    borderColor: nil
)

if let thumbImageUrlUW = valueUW.thumbImageUrl {
    UIImageView().sd_setImage(
        with: URL(string: thumbImageUrlUW),
        placeholderImage: nil,
        context: [.imageTransformer: transformer]
    ) { (thumbImage, _, _, _) in
        if let thumbImageUW = thumbImage {
            valueUW.thumbImage = thumbImageUW
            colorsUW[index] = valueUW
            self.tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
        }
    }
}

方案B:直接给UIImageView设置Layer圆角

如果图片尺寸固定,直接对UIImageView的Layer设置圆角,性能开销远低于修改图片本身,还能避免重复绘制:

// 在Cell的初始化或配置方法中设置
imageView.layer.cornerRadius = imageSize.width / 2
imageView.layer.masksToBounds = true
// 开启光栅化优化性能
imageView.layer.shouldRasterize = true
imageView.layer.rasterizationScale = UIScreen.main.scale

这种方式无需在SDWebImage回调中处理图片,只需配置视图属性即可,是UITableView场景下最轻量化的圆角实现方式。

3. 额外优化建议

  • 避免在回调中使用remove(at:)+insert(at:)修改数组,直接修改对应索引的元素即可,减少数组操作开销。
  • 给UIImageView设置占位图,提升滚动时的视觉体验,避免空白闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:21:49