首页 > 解决方案 > 使用图像缓存时展开 [String] 的问题

问题描述

我正在尝试重写我的图像缓存以摆脱使用 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
            })
        }

标签: iosswift

解决方案


你实际上是在强制展开allValues[String]所以没有什么可沮丧的。还将类型从字符串数组更改为单个字符串

所以而不是在可选绑定中

as! [String]

用这个

as? String

所以...

if let avatarImageUrlString = self.chatVC?.avatarDictionary.allValues[indexPath.row] as? String, let imageUrl = URL(string: avatarImageUrlString) {
    ...
}

推荐阅读