2

UIImageView を含むカスタム TableViewCells を持つ UITableView を持つ iOS アプリがあります。画像は Web サービスから読み込まれるため、最初の読み込み時に「読み込み中」の画像を表示し、gcd を使用してディスパッチし、そのセルのデータに一致する画像を取得します。

DISPATCH_QUEUE_PRIORITY_HIGH グローバル キューを使用してイメージ フェッチを実行すると、散発的に間違ったイメージがテーブルビュー セルに読み込まれます。独自のカスタム キューを使用すると、正しい画像がセルに取り込まれますが、テーブルビューのパフォーマンスはひどいものです。

これがコードです...

    // See if the icon is in the cache
if([self.photoCache objectForKey:[sample valueForKey:@"api_id"]]){
    [[cell sampleIcon]setImage:[self.photoCache objectForKey:[sample valueForKey:@"api_id"]]];
}
else {
    NSLog(@"Cache miss");
        [cell.sampleIcon setImage:nil];
        dispatch_queue_t cacheMissQueue = dispatch_queue_create("cacheMissQueue", NULL);
        //dispatch_queue_t cacheMissQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
        dispatch_async(cacheMissQueue, ^{
            if(sample.thumbnailFilename && sample.api_id){
                NSData *thumbNailData = [[NSData alloc] initWithContentsOfFile:sample.thumbnailFilename];
                UIImage *thumbNailImage = [[UIImage alloc]initWithData:thumbNailData];
                if(thumbNailImage){
                    // Set the cell
                    dispatch_sync(dispatch_get_main_queue(), ^{
                        [[cell sampleIcon]setImage:thumbNailImage];
                        [cell setNeedsLayout];
                    });
                    // save it to cache for future references
                    NSLog(@"DEBUG: Saving to cache %@ for sample %@",sample.thumbnailFilename,[sample objectID]);
                    [self.photoCache setObject:thumbNailImage forKey:sample.api_id];
                }
            }
        });
        dispatch_release(cacheMissQueue);
}
4

2 に答える 2

1

WWDC 2012 セッション #211 を視聴することは大いに役立ち、コードを GCD の使用から NSOperationQueue に変更したところ、問題が解決しました。

新しいコード...

[[self imgQueue]addOperationWithBlock:^{
            if(sample.thumbnailFilename && sample.api_id){
                NSData *thumbNailData = [[NSData alloc] initWithContentsOfFile:sample.thumbnailFilename];
                UIImage *thumbNailImage = [[UIImage alloc]initWithData:thumbNailData];
                if(thumbNailImage){
                    // Set the cell
                    [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                        [[cell sampleIcon]setImage:thumbNailImage];
                        [cell setNeedsLayout];
                    }];
                    // save it to cache for future references
                    [self.photoCache setObject:thumbNailImage forKey:sample.api_id];
                }
            }

        }];
于 2012-08-09T02:49:21.493 に答える
0

最終的に画像を取得するときは、セルのindexPathと画像の間に関連付けが必要です。これはバックグラウンドスレッド上にあるため、ブロックを使用して、そのような画像が利用可能であることをmainQueueに通知することをお勧めします。メインスレッドでのみ、表示されているセルの配列をtableViewに要求します。画像があるセルが表示されている場合は、その時点で画像を直接設定できます(メインスレッドでは、セルがわかります)。が表示されており、この実行ループの反復では変更されません。)セルが表示されていない場合は、問題ありません。次にそのセルがスコープに入ると、画像が待機します。私は今私のアプリでこれを行っています、それは何ヶ月も出ていて、そしてそれはすべてうまく機能していて、応答性について良いレビューを得ています(あなたがこれをするならあなたのアプリがそうするのと同じように!)

于 2012-08-03T18:07:17.873 に答える