我正在尝试为 UIImageView 添加一个扩展以异步加载图像,但它抛出了一个错误。迅速



由于声明常量而导致第3行出现错误,为什么会发生这种情况?错误:扩展不能包含存储的属性代码:

extension UIImageView {
let imageCache = NSCache<NSString, UIImage>() //error

func imageFromServerURL(_ URLString: String, placeHolder: UIImage?) {
self.image = nil
//If imageurl's imagename has space then this line going to work for this
let imageServerUrl = URLString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
if let cachedImage = imageCache.object(forKey: NSString(string: imageServerUrl)) {
self.image = cachedImage
return
}
if let url = URL(string: imageServerUrl) {
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
//print("RESPONSE FROM API: (response)")
if error != nil {
print("ERROR LOADING IMAGES FROM URL: (String(describing: error))")
DispatchQueue.main.async {
self.image = placeHolder
}
return
}
DispatchQueue.main.async {
if let data = data {
if let downloadedImage = UIImage(data: data) {
self.imageCache.setObject(downloadedImage, forKey: NSString(string: imageServerUrl))
self.image = downloadedImage
}
}
}
}).resume()
}
}
}

我使用了这个代码,不明白为什么它不起作用:Swift异步加载镜像

是的,扩展可能不会添加存储的属性。这样做可能是最好的,这样您的类就不会因为库通过添加一些可能对您不感兴趣的附加信息来扩展类而增加大小。

但在您的情况下,您可能甚至不想拥有存储的属性。编码方式意味着每个UIImageView实例都有自己的缓存。因此,例如,显示每个单元格的图像视图的表视图意味着每个可见单元格的缓存,这会导致同一图像的多次下载,而不是共享

在您的情况下,这个问题的最佳解决方案可能是使其保持静态:

extension UIImageView {
private static let imageCache = NSCache<NSString, UIImage>()
private var imageCache: NSCache<NSString, UIImage> { UIImageView.imageCache }

func imageFromServerURL(_ URLString: String, placeHolder: UIImage?) {
self.image = nil
// If image url's image name has space then this line going to work for this
let imageServerUrl = URLString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
if let cachedImage = imageCache.object(forKey: NSString(string: imageServerUrl)) {
self.image = cachedImage
return
}
if let url = URL(string: imageServerUrl) {
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
//print("RESPONSE FROM API: (response)")
if error != nil {
print("ERROR LOADING IMAGES FROM URL: (String(describing: error))")
DispatchQueue.main.async {
self.image = placeHolder
}
return
}
DispatchQueue.main.async {
if let data = data {
if let downloadedImage = UIImage(data: data) {
self.imageCache.setObject(downloadedImage, forKey: NSString(string: imageServerUrl))
self.image = downloadedImage
}
}
}
}).resume()
}
}

}

除了你的问题,你应该知道,你试图解决的任务可能没有你提供的代码那么容易。我在你的代码中看到至少有两个主要问题:

  1. 当多次快速调用此方法时,您可能会遇到竞争条件,第一次调用将比第二次调用晚下载映像。在这种情况下,将显示第一个图像,而不是第二个(最后一个(图像
  2. 当为同一图像多次调用此方法时,您将多次在同一资源上启动下载(屏幕的两个位置显示相同的图像将下载两次(

然后可能还有更多。例如,这一切都在记忆中。在内存耗尽之前,您预计可以缓存多少图像?也许最好把它移到一些文件系统中。

相关内容

  • 没有找到相关文章

最新更新