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

这就是我正在做的事情。

我没有直接使用单元格,而是传入索引路径

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 回答
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 的示例一样,滚动时不要为单元格加载图像
  • 将下载操作添加到 anNSOperationQueue并优先考虑最近请求的操作(取消已滚动的操作的优先级)
  • 将下载的图像保存到文件系统并首先检查那里
于 2012-05-01T04:40:17.690 回答