注意:请没有库。 这对我来说很重要。另外,对此有各种各样的答案,但我发现没有一个能很好地解决该问题。请不要将其标记为重复项。提前致谢!
我的问题是,如果您在表中快速滚动,会看到旧图像并闪烁。
URLSession
这是我到目前为止的内容:
图像缓存类
class Cache { static let shared = Cache() private let cache = NSCache<NSString, UIImage>() var task = URLSessionDataTask() var session = URLSession.shared func imageFor(url: URL, completionHandler: @escaping (image: Image? error: Error?) -> Void) { if let imageInCache = self.cache.object(forKey: url.absoluteString as NSString) { completionHandler(image: imageInCache, error: nil) return } self.task = self.session.dataTask(with: url) { data, response, error in if let error = error { completionHandler(image: nil, error: Error) return } let image = UIImage(data: data!) self.cache.setObject(image, forKey: url.absoluteString as NSString) completionHandler(image: image, error: nil) } self.task.resume() } }
用法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let myImage = images[indexPath.row] if let imageURL = URL(string: myImage.urlString) { photoImageView.setImage(from: imageURL) } return cell }
有什么想法吗?
几个问题:
image
nil
UIImageView
例如:
extension UIImageView { func setImage(from url: URL, placeholder: UIImage? = nil) { image = placeholder // use placeholder (or if `nil`, remove any old image, before initiating asynchronous retrieval ImageCache.shared.image(for: url) { [weak self] result in switch result { case .success(let image): self?.image = image case .failure: break } } } }
这里的窍门是,如果在UIImageView扩展中执行此操作,则不能仅创建新的存储属性来跟踪旧请求。因此,您通常会使用“关联值”来跟踪先前的请求。