1

以下で loadImage のコールバック ブロックが実行されると、テーブル セルが再利用された可能性があります。したがって、「imageView」に適用される画像は、この再利用されたセルには関係なく、古いセルの画像です。

画像を持つセルごとに識別子を一意にすると、問題はなくなります。しかし、これは多くの結果でパフォーマンスが低下します。

コールバック ブロックで同じ再利用識別子を何らかの形で使用して、画像を正しいセルに表示することはできますか?

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSDictionary *place;
    PlaceTableViewCell *cell; // UITableViewCell subclass
    NSString *identifier = @"PlaceTableViewCell";

    if (cell == nil) {

        NSArray *objects;

        objects = [[NSBundle mainBundle] loadNibNamed:@"PlaceTableViewCell" owner:self options:nil];

        for(id object in objects) {

            if([object isKindOfClass:[PlaceTableViewCell class]]) {                
                cell = (PlaceTableViewCell *)object;                
                break;
            }
        }
    }

    UIImageView *imageView;
    if((imageView = (UIImageView*)[cell viewWithTag:1])) {

        NSString *filename;
        int placeImageId = 0;
        place = [places objectAtIndex:indexPath.row];

        if(place) {

            placeImageId = [[d objectForKey:@"placeImageId"] intValue];

            if(placeImageId) {

                [[RestAPIConnector sharedInstance] loadImage :placeImageId :@"thumb" :^(NSString *response){

                    NSDictionary *image = [response JSONValue];

                    if ([image objectForKey:@"img"]) {

                        NSString *b64Img = [image objectForKey:@"img"];
                        UIImage *ui = [UIImage imageWithData:[Base64 decode:b64Img]];

                        imageView.image = ui;
                    }
                }];            
            }
        }
    }

    return cell;
}
4

2 に答える 2

1

画像を保持する辞書を作成してから、辞書から読み取ろうとします。cellForRowAtIndexPath:

@property(retain)NSMutableDictionary *imageData;

//...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //...

    UIImageView *imageView;
    if((imageView = (UIImageView*)[cell viewWithTag:1])) {
        int placeImageId = 0;
        place = [places objectAtIndex:indexPath.row];
        if(place) {
            placeImageId = [[d objectForKey:@"placeImageId"] intValue];
            if(placeImageId) {
                NSObject *image = [imageData objectForKey:[NSNumber numberWithInt:placeImageId]];
                if ([image isKindOfClass:[UIImage class]) {
                    imageView.image = (UIImage *)image;
                } else if (![image isEqual:@"downloading"]) {
                    [imageData addObject:@"downloading" forKey:[NSNumber numberWithInt:placeImageId]];
                    [[RestAPIConnector sharedInstance] loadImage:placeImageId onSuccess:^(NSString *response){
                        NSDictionary *image = [response JSONValue];
                        if ([image objectForKey:@"img"]) {
                            NSString *b64Img = [image objectForKey:@"img"];
                            [imageData addObject:[UIImage imageWithData:[Base64 decode:b64Img]] forKey:[NSNumber numberWithInt:placeImageId]];
                        }
                    }];            
                }
            }
        }
    }
    return cell;
}

いくつかの潜在的な最適化:

  • @ Jun1stのサンプルのように、スクロール中にセルの画像を読み込まないでください
  • にダウンロード操作を追加し、NSOperationQueue最後に要求されたものを最初に優先します(スクロールしたものの優先順位を下げます)
  • ダウンロードした画像をファイルシステムに保存し、最初に確認してください
于 2012-05-01T04:40:17.690 に答える
1

これが私がやっていることです。

セルを直接使用する代わりに、インデックス パスを渡しています。

if(user.profileImage == nil)
{
    if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
        NSLog(@"file for user %d doesn't exist", [user.userId intValue]);
        [self startUserProfileImageDownload:user forIndexPath:indexPath];
    }
}
else
{
    cell.profileImageView.image = user.profileImage;

}

ダウンロードが完了したら、インデックス パスを使用してセルを取得し、画像を更新します。

MessageCell *cell = (MessageCell *)[self.tableView cellForRowAtIndexPath:path];

// Display the newly loaded image
cell.profileImageView.image = user.profileImage;
CALayer *roundedLayer = [cell.profileImageView layer];

MessageCell は私のカスタム セルです。顧客セルを使用していない場合は、Tag を使用して imageView を取得できます。

于 2012-04-27T02:33:00.670 に答える