0

非同期的に画像を UITableView にロードしていますが、各行には異なる画像があります。問題は、UITableView をスクロールすると、以前の画像が新しい行に再度読み込まれ、しばらくするとこれらの画像が正しい画像に変更されることです (この問題はdequeueReusableCellWithIdentifierを削除すると解消されますが、パフォーマンスが低下します)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
     static NSString *cellIdentifier = @"Cell"; 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

     if(cell == nil) {
        NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCellFriends" owner:self options:nil];
        cell = [nibObjects objectAtIndex:0];  
        nibObjects = nil;
     } 

     UIImageView *avatar = (UIImageView *)[cell viewWithTag:100];
     UILabel *name = (UILabel *)[cell viewWithTag:2];
     UILabel *city = (UILabel *)[cell viewWithTag:3];

     EntryProfile *entryForRow = [entriesProfileArray objectAtIndex:indexPath.row];


    avatar.image = nil;

     NSString *strLinkImage = [entryForRow.apiAvatarPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
     NSArray *args = [NSArray arrayWithObjects:avatar,strLinkImage,[NSString stringWithFormat:@"%d",indexPath.row], nil];
     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(addPhotoWithImageView:) object:args];
     [operationQueue addOperation:operation];
     [operation release];

     // Set the name of the user
     name.text = entryForRow.name;

     return cell;
}

// Method 
- (void)addPhotoWithImageView:(NSArray *)args
{
    UIImageView *imageView = (UIImageView *)[args objectAtIndex:0];
    NSString *strLinkImage = (NSString *)[args objectAtIndex:1];
    NSString *index = (NSString *)[args objectAtIndex:2];

    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.example.com%@",strLinkImage]]];
    UIImage *imageField = [[UIImage alloc] initWithData:imageData];

    if (imageData) {
        [imageView performSelectorOnMainThread:@selector(setImage:) withObject:imageField waitUntilDone:NO];
    }
    [imageField release];
 }
4

5 に答える 5

3

まだこの問題に直面している人がいる場合、上記の回答は実際には役に立たないことがわかります.

2 つのステップ:

  • 画像ビューに対して進行中の非同期リクエストを「キャンセル」し、非同期リクエストが通過するまで、プレースホルダー画像を使用して新しい画像を非同期に設定する必要があります
  • 理想的には、ユーザーがスクロールしている間は非同期リクエストを送信しないでください (テーブルビュー/スクロールビューが減速しています) - 新しいリクエストを作成しないようにして、そのような場合はプレースホルダーを設定してください (リクエストが完了したことを自信を持って知る方法がない限り)そのため、画像 URL のローカル ディスク キャッシュで画像が見つかる可能性があります)。

上記の 2 つの手順により、機能が意図したとおりに維持され、パフォーマンスも向上します。

于 2012-11-13T17:22:02.880 に答える
0

先日同様の問題が発生しましたが、解決方法は次のとおりです(パフォーマンスの低下は見られませんでした)。

UITableViewCell*セル;

if(cell == nil){
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

//残りのコード

}

したがって、基本的にif内でデキューを呼び出します。

于 2012-05-11T07:20:11.547 に答える
0

cellForRowAtIndexPath で、呼び出す前に:

 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(addPhotoWithImageView:) object:args];

yourCell imageView.image を nil に強制します

imageView.image = nil;

このようにして、古いセルの内容画像を消去すると、ロード時に正しい画像で再描画されます...

編集

たぶん nil は機能しません...

プレースホルダー画像、実際のpngファイルを試してください(テスト用に色を付けた場合、透明なファイルになる可能性があります...)

于 2012-05-10T12:01:10.400 に答える
0

独自の UItableViewCell を実装し、PrepareForReuse メソッドですべてのセル プロパティを nil に設定してみてください。

また、非同期的にリモート イメージをロードするために、このプロジェクトを参照することをお勧めします: https://github.com/nicklockwood/AsyncImageView

さまざまなプロジェクトで大成功を収めました。

于 2012-05-10T12:15:35.830 に答える
0

これは古典的な問題で、簡単に解決できます。

cellForRowAtIndexPath:実装では、次のようなコードを含めることができます。

if (!tableView.decellerating) {
    // set avatar.image to its correct UIImage value how ever you like, 
    // in the background if necessary
} else {
    // table is scrolling...
    avatar.image = nil;
}

次に、View Controller にこのメソッドを実装します。

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSArray *visibleCells = [self.tableView visibleCells];
    [visibleCells enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UITableViewCell *cell = (UITableViewCell *)obj;
        UIImageView *avatar = (UIImageView *)[cell viewWithTag:100];
        avatar.image = ...; // セルに画像を設定するために必要なことを行います
    }];
}

UIScrollViewDelegateまた、View Controller が採用するプロトコルのリストに追加する必要があります。

ここでの考え方は、テーブル ビューが移動している限り、わざわざ画像をロードしないということです。あなたのパフォーマンスは飛躍的に向上します。

于 2012-11-13T17:32:44.640 に答える