由于声明了一个常数而在第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异步加载图像
As扩展不能包含存储的属性,因此您可以将其设为全局变量,并从self.imageCache.setObject(downloadedImage,forkey:NSString(string:imageServerUrl))
中删除self
let imageCache = NSCache<NSString, UIImage>()
或
class SubImg: UIImageView {}
是,扩展可能不会添加存储的属性。这可能是最好的方法,这样您的类不会因为库而增加大小,因为库通过添加一些额外的信息来扩展您的类,而这些信息对您来说很可能是不感兴趣的。
但在您的情况下,您可能甚至不想拥有一个存储的财产。您的编码方式意味着您的每个UIIimageView
实例都有自己的缓存。因此,例如,每个单元格显示图像视图的表视图意味着每个可见单元格的缓存,这导致同一图像的多次下载,而不是共享它。
在您的情况下,解决此问题的最佳方案可能是使其静态化:
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()
}
}
}
撇开你的问题不谈,你应该知道你试图解决的任务可能没有你提供的代码那么容易。我在您的代码中看到至少有2个主要问题:
而且可能还有更多的。例如,这都在内存中。在内存耗尽之前,您希望可以缓存多少映像?也许最好将它移到某个文件系统中。