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

Swift 5用URLSession实现tableView图片缓存及代码报错解决

错误原因分析

  • 错误1、错误3的根源是NSCache泛型参数使用错误:NSCache<KeyType, ObjectType>的第一个参数是缓存键的类型,第二个是缓存对象的类型,你的代码写反了两个参数的顺序;同时NSCache要求键必须是继承自NSObject的类类型,Swift原生String是结构体类型,不满足要求,所以触发类类型要求报错。
  • 错误2的根源是NSCache不支持Swift下标语法直接赋值/取值,只能用官方提供的setObject(_:forKey:)存、object(forKey:)取。
  • 额外隐含问题:你把imageCache定义在configure函数内部,每次调用函数都会新建缓存实例,完全无法实现缓存复用的效果,需要把缓存放到函数外部全局复用。

修正后代码

// 缓存放到函数外部,比如作为当前UITableViewCell类的静态属性,保证全局复用
static let imageCache = NSCache<NSString, UIImage>()

func configure(with urlString: String, name: String, address: String, station: String) {
    loader.startAnimating()
    loader.isHidden = false
    locationImageView.image = nil // 清空旧图片,避免cell复用出现图片错乱
    
    // 优先查缓存,命中就直接返回不用走网络请求
    if let cachedImage = Self.imageCache.object(forKey: urlString as NSString) {
        self.locationImageView.image = cachedImage
        self.nameLabel.text = name
        self.addressLabel.text = address
        self.loader.stopAnimating()
        self.loader.isHidden = true
        return
    }
    
    guard let url = URL(string: urlString) else {
        loader.stopAnimating()
        loader.isHidden = true
        return
    }
    
    let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
        guard let data = data, error == nil, let locationImage = UIImage(data: data) else {
            DispatchQueue.main.async {
                self?.loader.stopAnimating()
                self?.loader.isHidden = true
            }
            return
        }
        
        // 存入缓存,将String转成NSString满足类类型要求
        Self.imageCache.setObject(locationImage, forKey: urlString as NSString)
        
        DispatchQueue.main.async {
            self?.nameLabel.text = name
            self?.addressLabel.text = address
            self?.locationImageView.image = locationImage
            self?.loader.stopAnimating()
            self?.loader.isHidden = true
        }
    }
    task.resume()
}

额外优化说明

  • 增加了cell复用防护,避免UITableView滑动时出现旧图片闪烁的问题
  • 增加了缓存命中逻辑,重复加载同一张图片时不会重复发起网络请求
  • 去掉了原图的强制解包逻辑,避免无效图片数据导致的崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:57:03