リモートサイトからUITableViewにサムネイル画像を読み込もうとしています。これを非同期で実行したいのですが、サムネイル画像用に貧乏人のキャッシュを実装したいと思います。これが私のコードスニペットです(問題のある動作については以下で説明します):
@property (nonatomic, strong) NSMutableDictionary *thumbnailsCache;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// ...after obtaining the cell:
NSString *thumbnailCacheKey = [NSString stringWithFormat:@"cache%d", indexPath.row];
if (![[self.thumbnailsCache allKeys] containsObject:thumbnailCacheKey]) {
// thumbnail for this row is not found in cache, so get it from remote website
__block NSData *image = nil;
dispatch_queue_t imageQueue = dispatch_queue_create("queueForCellImage", NULL);
dispatch_async(imageQueue, ^{
NSString *thumbnailURL = myCustomFunctionGetThumbnailURL:indexPath.row;
image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:thumbnailURL]];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithData:image];
});
});
dispatch_release(imageQueue);
[self.thumbnailsCache setObject:image forKey:thumbnailCacheKey];
} else {
// thumbnail is in cache
NSData *image = [self.thumbnailsCache objectForKey:thumbnailCacheKey];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithData:image];
});
}
したがって、問題のある動作は次のとおりです。
UITableViewが読み込まれると、サムネイルはセルの初期セットに表示されません。セルが画面から移動してから上に移動した場合にのみ、サムネイルが表示されます。
キャッシュがまったく機能していません。私の知る限り、サムネイルをキャッシュに保存することはできません。つまり、この行は失敗します。
[self.thumbnailsCache setObject:image forKey:thumbnailCacheKey];
GCDキューは、セルごとに作成/解放されます。さらに、キュー名は毎回同じです。これは悪い習慣ですか?
間違っていると思われることや、一般的なアプローチのコメントを指摘していただければ幸いです。ありがとう。
アップデート:
解決済み:reloadRowsAtIndexPathsの呼び出しを追加したところ、サムネイル画像が表示される最初の行に読み込まれるようになりました
解決済み:失敗した理由は、他のスレッドがそのオブジェクトの設定を完了する前に、画像オブジェクトをディクショナリに追加していたためです。プロパティディクショナリにオブジェクトを追加するインスタンスメソッドを作成しました。これにより、ブロック内からオブジェクトを呼び出すことができ、画像オブジェクトの設定後にオブジェクトが追加されるようになります。