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) } } } }
额外优化建议
- 避免强制解包:原代码中
kategoriItem.image!存在崩溃风险,建议添加可选绑定:
if let imagePath = kategoriItem.image { cell.parentCategoryImageView.load(urlString: base_img + imagePath) } else { // 设置默认占位图 cell.parentCategoryImageView.image = UIImage(named: "default_placeholder") }
- 优化TableView性能:确保
kategoriManager.kategoriItem(at:)是O(1)访问效率(比如内部用数组存储数据),避免在cellForRowAt中执行耗时操作。
内容的提问来源于stack exchange,提问作者Andikatama
相关产品推荐
相关产品推荐

