我正试图重写图像缓存以摆脱使用Alamofire的麻烦,这样做时我遇到了错误。以前,我的图片缓存代码是:
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView {
func loadImageUsingCacheWithUrlString(_ urlString: String) {
self.image = nil
// Check cache for image first
if let cachedImage = imageCache.object(forKey: urlString as NSString) {
self.image = cachedImage
return
}
// Otherwise fire off a new download
Alamofire.request(urlString)
.responseImage { response in
if let downloadedImage = response.result.value {
// image is here.
imageCache.setObject(downloadedImage, forKey: urlString as NSString)
self.image = downloadedImage
}
}
}
}
示例用法如下:
navBarCell.avatarImageView.loadImageUsingCacheWithUrlString(avatars[indexPath.row])
现在,我已经像这样重写了缓存:
class ImageService {
static let cache = NSCache<NSString, UIImage>()
static func downloadImage(url: URL, completion: @escaping (_ image: UIImage?) -> (Void)) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else {return}
var downloadedImage: UIImage?
downloadedImage = UIImage(data: data)
if downloadedImage != nil {
cache.setObject(downloadedImage!, forKey: url.absoluteString as NSString)
}
DispatchQueue.main.async {
completion(downloadedImage)
}
}.resume()
}
static func getImage(url: URL, completion: @escaping (_ image: UIImage?) -> (Void)) {
if let image = cache.object(forKey: url.absoluteString as NSString) {
completion(image)
} else {
downloadImage(url: url, completion: completion)
}
}
}
并在与上述相同的情况下使用它:
if let avatarImageUrlString = self.chatVC?.avatarDictionary.allValues as! [String], let imageUrl = URL(string: avatarImageUrlString) {
ImageService.getImage(url: imageUrl, completion: { (image) -> (Void) in
navBarCell.avatarImageView.image = image
})
}
我在Initializer for conditional binding must have Optional type, not '[String]'
语句中收到错误if let
。
我不确定如何处理-我需要[String]
数组,但是如果我正确理解错误,它需要是可选的,而不是用as! [String]
强制展开?如果这是一个新手问题,我深表歉意,但似乎无法正常工作。
感谢您的指导!
编辑:
我尝试将let avatarImageUrlString....
放在if let
之外:
let avatarImageUrlString = self.chatVC?.avatarDictionary.allValues as! [String]
if let imageUrl = URL(string: avatarImageUrlString) {
ImageService.getImage(url: imageUrl, completion: { (image) -> (Void) in
navBarCell.avatarImageView.image = image
})
}
但是在Cannot convert value of type '[String]' to expected argument type 'String'
行出现错误if let
。
我还尝试了删除!
并收到错误'[Any]?' is not convertible to '[String]'; did you mean to use 'as!' to force downcast?
,并提出了将!
放回Replace 'as' with 'as!'
编辑2:
if let avatarImageUrlString = self.chatVC?.avatarDictionary.allValues as? [String], let imageUrl = URL(string: avatarImageUrlString[0]) {
ImageService.getImage(url: imageUrl, completion: { (image) -> (Void) in
navBarCell.avatarImageView.image = image
})
}
编辑3:
let avatars = self.chatVC?.avatarDictionary.allValues[indexPath.row] as? [String]
if let avatarImageUrlString = avatars, let imageUrl = URL(string: avatarImageUrlString[0]) {
ImageService.getImage(url: imageUrl, completion: { (image) -> (Void) in
navBarCell.avatarImageView.image = image
})
}
答案 0 :(得分:1)
您实际上是将allValues
强制展开为[String]
,所以没有什么可以降低的。还将类型从字符串数组更改为单个字符串
因此,而不是在可选绑定中
as! [String]
使用此
as? String
所以...
if let avatarImageUrlString = self.chatVC?.avatarDictionary.allValues[indexPath.row] as? String, let imageUrl = URL(string: avatarImageUrlString) {
...
}