pt 26、2021、TIL(Today I Learned)-属性の計算、拡張、キャッシュで処理できない問題TroubleShooting
17727 ワード
Truble:キャッシュの問題を処理できません
extension OpenMarketListCollectionViewCell {
// MARK: - configure cell
func configure(itemInformation: [OpenMarketItem], index: Int) {
let thumbnailDownloadLink = itemInformation[index].thumbnails[0]
self.itemThumbnail.applyDownloadedImage(link: thumbnailDownloadLink )
}
}
ネットワーク通信によってロードされた画像を商品リストに適用するために、上記のapplyDownloadedImage()
の方法を用いた.extension UIImageView {
private var imageLoader: CachedImageLoader {
return CachedImageLoader(imageDownloader: ImageDownloader(network: Network()))
}
func applyDownloadedImage(link: String) {
imageLoader.loadImageWithCache(with: link) { image in
DispatchQueue.main.async {
self.image = image
}
}
}
}
この方法は、UIImageView
を拡張し、imageLoader
メソッドによってCachedImageLoder
と呼ばれるタイプのモジュールを演算プログラムとして宣言し、loadImageWithCache()
メソッドによってイメージをロードする.final class CachedImageLoader {
private let cache = ImageCache<NSString, UIImage>()
private let imageDownloader: ImageDownloadable
init(imageDownloader: ImageDownloadable) {
self.imageDownloader = imageDownloader
}
func loadImageWithCache(with link: String, completion: @escaping (UIImage) ->()) {
let nsText = link as NSString
if let cachedImage = cache[nsText] {
return completion(cachedImage)
}
imageDownloader.downloadImage(url: link.createURL()) { result in
switch result {
case .failure(let error):
NSLog(error.localizedDescription)
case .success(let image):
self.cache.insert(image, forkey: nsText)
return completion(image)
}
}
}
}
CachedImageLoader
のタイプは次のとおりです.内部は
cache
およびimageDownloader
であり、imageDownloader
によって受信された初期イメージデータはクラス内部cacheに格納され、UIImgeに戻り、その後同じイメージが受信された場合、cache内部でイメージが存在するかどうかをチェックし、キャッシュに存在する場合、受信されたイメージ適用される論理.これは問題のない構造に見えますが、プロジェクトを実行すると、イメージがキャッシュできないことがわかります.何か問題がありますか.
TroubleShooting:計算プログラムのプログラム初期化の問題
こんな渋滞しているところがあったら、もちろん先に調整しなければなりませんよね?
真剣にデバッグしている間に変なところを見つけました.
CachedImageLoader
オブジェクトのself.cache.insert(image, forKey: nsText)
このセクションではbreakpointを撮影し、imageCacheを表示します.次のログが表示されます.<ImageCache<NSString, UIImage>: 0x60000330d580>
<ImageCache<NSString, UIImage>: 0x60000330d940>
<ImageCache<NSString, UIImage>: 0x60000330da80>
ブーブー!なんてことだ.INSERTの度にImageCacheのアドレスが違いますなぜかよく考えてみると...UIImageLoaderはUIImageViewの拡張から計算プログラムでロードされます.
private var imageLoader: CachedImageLoader {
return CachedImageLoader(imageDownloader: ImageDownloader(network: Network()))
}
これにより、新しいimageLoaderインスタンスが作成されるたびに、imageLoaderのキャッシュに画像が保存されます.(私はバカ…)したがって、各セルで
self.itemThumbnail.applyDownloadedImage(link: thumbnailDownloadLink )
操作を行うたびに、imageLoaderインスタンスのimageCacheに格納される――、――トラブルシューティング
UIImageView
の拡張では、ImageLoaderを使用してキャッシュを格納し、ViewControllerのImageLoaderを使用して画像キャッシュを格納し、CacheManager
クラスを作成しました.このクラスは、このときに単一のトーンモードを使用するのに最適なので、キャッシュを共通のストレージとして使用することができます.import UIKit
final class CacheManager {
let cache = ImageCache<NSString, UIImage>(totalCostLimit: 500 * 1024 * 1024)
static let shared = CacheManager()
private init() { }
}
CachedImageLoaderの内部を変更しました.func loadImageWithCache(with link: String, completion: @escaping (UIImage) ->()) {
let nsText = link as NSString
if let cachedImage = CacheManager.shared.cache[nsText] {
return completion(cachedImage)
}
imageDownloader.downloadImage(url: link.createURL()) { result in
switch result {
case .failure(let error):
NSLog(error.localizedDescription)
case .success(let image):
CacheManager.shared.cache.insert(image, forkey: nsText)
return completion(image)
}
}
}
これにより、イメージが正常にキャッシュに格納されることを確認できます.の最後の部分
今日また1つの拡張と演算プログラムを理解して、私はとても喜んでいます!これからは二度と今日のようなミスを犯すことはありません!!
Reference
この問題について(pt 26、2021、TIL(Today I Learned)-属性の計算、拡張、キャッシュで処理できない問題TroubleShooting), 我々は、より多くの情報をここで見つけました https://velog.io/@inwoodev/Sept-26-2021-TIL-Today-I-Learned-Computed-Property-Extension-캐시처리가-안되는-문제-TroubleShootingテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol