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

Swift控制器加载时预加载TableView所有图片的原生实现方案

解决方案

一、修复当前可见cell图片不显示问题

你当前使用Data(contentsOf:)同步加载网络数据,这种方式会阻塞后台线程,导致图片加载缓慢,只有滚动复用cell时缓存已存在才会显示。换成URLSession异步请求,能更高效处理网络加载,避免线程阻塞:

class CustomImageView: UIImageView {
    var imageURLString: String?
    // 全局缓存(确保为全局实例,可在类外单独声明)
    static let imageCache = NSCache<NSString, UIImage>()

    func load(urlString: String) {
        imageURLString = urlString
        image = nil

        // 优先读取缓存
        if let cachedImage = CustomImageView.imageCache.object(forKey: urlString as NSString) {
            self.image = cachedImage
            return
        }

        guard let url = URL(string: urlString) else {
            print("无效的图片URL")
            return
        }

        // 用URLSession异步加载图片
        let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            guard let self = self, error == nil, let data = data, let imageToCache = UIImage(data: data) else {
                print("图片加载失败: \(error?.localizedDescription ?? "未知错误")")
                return
            }

            DispatchQueue.main.async {
                // 避免cell复用导致的图片错位
                if self.imageURLString == urlString {
                    self.image = imageToCache
                }
                // 存入缓存
                CustomImageView.imageCache.setObject(imageToCache, forKey: urlString as NSString)
            }
        }
        task.resume()
    }
}

二、实现不滚动加载所有图片(预加载缓存)

如果希望TableView初始化后,所有图片(包括不可见cell的)都提前加载到缓存,可以在数据获取完成后,遍历所有图片URL进行预加载:

kategoriManager.fetch(){ [weak self] kategoriItem, error in
    DispatchQueue.main.async {
        guard let self = self else { return }
        // 更新TableView
        self.parentCategoryTableView.reloadData()
        
        // 后台线程预加载所有图片到缓存
        DispatchQueue.global().async {
            for index in 0..<self.kategoriManager.kategoriCount() { // 假设kategoriManager有获取数据总数的方法
                let item = self.kategoriManager.kategoriItem(at: index)
                guard let imagePath = item.image else { continue }
                let fullURL = self.base_img + imagePath
                // 创建临时实例加载图片,仅用于填充缓存
                let tempImageView = CustomImageView()
                tempImageView.load(urlString: fullURL)
            }
        }
    }
}

额外优化建议

  1. 避免强制解包:原代码中kategoriItem.image!存在崩溃风险,建议添加可选绑定:
if let imagePath = kategoriItem.image {
    cell.parentCategoryImageView.load(urlString: base_img + imagePath)
} else {
    // 设置默认占位图
    cell.parentCategoryImageView.image = UIImage(named: "default_placeholder")
}
  1. 优化TableView性能:确保kategoriManager.kategoriItem(at:)是O(1)访问效率(比如内部用数组存储数据),避免在cellForRowAt中执行耗时操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:12:53