缓存图像时为零
Nil while caching images
我已经能够解决缓存图像的问题以提高我的应用程序的滚动性能。然而,当它试图将它添加到 cache 时,却发现 nil。另外,如何为加载失败或不可用的图像添加占位符图像?
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func downloadImage(from imgURL: String) -> URLSessionDataTask? {
guard let url = URL(string: imgURL) else { return nil }
// set initial image to nil so it doesn't use the image from a reused cell
image = nil
// check if the image is already in the cache
if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
self.image = imageToCache
return nil
}
// download the image asynchronously
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let err = error {
print(err)
return
}
DispatchQueue.main.async {
// create UIImage
let imageToCache = UIImage(data: data!)
// add image to cache
imageCache.setObject(imageToCache!, forKey: imgURL as NSString)
self.image = imageToCache
}
}
task.resume()
return task
}
}
一些观察:
只需提供 placeholder
作为函数的参数并使用它代替 nil
来初始化 image
.
检查缓存后执行此操作(因为如果您在缓存中找到所需图像,则使用占位符毫无意义)。
避免使用 !
强制展开运算符。
检查 UIImage(data:)
在 guard
语句中(在会话队列中,而不是在主线程中)找到图像。
因此:
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func downloadImage(from imgURL: String, placeholder: UIImage? = nil) -> URLSessionDataTask? {
guard let url = URL(string: imgURL) else { return nil }
// check if the image is already in the cache
if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
image = imageToCache
return nil
}
// set initial image to placeholder so it doesn't use the image from a reused cell
image = placeholder
// download the image asynchronously
let task = URLSession.shared.dataTask(with: url) { data, _, error in
guard
let data = data,
error == nil,
let imageToCache = UIImage(data: data)
else {
print(error ?? URLError(.badServerResponse))
return
}
imageCache.setObject(imageToCache, forKey: imgURL as NSString)
DispatchQueue.main.async {
self.image = imageToCache
}
}
task.resume()
return task
}
}
我已经能够解决缓存图像的问题以提高我的应用程序的滚动性能。然而,当它试图将它添加到 cache 时,却发现 nil。另外,如何为加载失败或不可用的图像添加占位符图像?
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func downloadImage(from imgURL: String) -> URLSessionDataTask? {
guard let url = URL(string: imgURL) else { return nil }
// set initial image to nil so it doesn't use the image from a reused cell
image = nil
// check if the image is already in the cache
if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
self.image = imageToCache
return nil
}
// download the image asynchronously
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let err = error {
print(err)
return
}
DispatchQueue.main.async {
// create UIImage
let imageToCache = UIImage(data: data!)
// add image to cache
imageCache.setObject(imageToCache!, forKey: imgURL as NSString)
self.image = imageToCache
}
}
task.resume()
return task
}
}
一些观察:
只需提供
placeholder
作为函数的参数并使用它代替nil
来初始化image
.检查缓存后执行此操作(因为如果您在缓存中找到所需图像,则使用占位符毫无意义)。
避免使用
!
强制展开运算符。检查
UIImage(data:)
在guard
语句中(在会话队列中,而不是在主线程中)找到图像。
因此:
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func downloadImage(from imgURL: String, placeholder: UIImage? = nil) -> URLSessionDataTask? {
guard let url = URL(string: imgURL) else { return nil }
// check if the image is already in the cache
if let imageToCache = imageCache.object(forKey: imgURL as NSString) {
image = imageToCache
return nil
}
// set initial image to placeholder so it doesn't use the image from a reused cell
image = placeholder
// download the image asynchronously
let task = URLSession.shared.dataTask(with: url) { data, _, error in
guard
let data = data,
error == nil,
let imageToCache = UIImage(data: data)
else {
print(error ?? URLError(.badServerResponse))
return
}
imageCache.setObject(imageToCache, forKey: imgURL as NSString)
DispatchQueue.main.async {
self.image = imageToCache
}
}
task.resume()
return task
}
}