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个步骤:

  • 您需要“取消”正在进行的图像视图异步请求,然后使用占位符图像异步设置新图像,直到异步请求通过
  • 理想情况下,不要在用户滚动时发送异步请求(tableview/scrollview 正在减速) - 尽量避免发出新请求并在这种情况下设置占位符(除非您有信心知道请求已完成)之前,因此很可能在图像 url 的本地磁盘缓存中找到图像)

以上 2 个步骤将使您的功能保持预期,并为您提供良好的性能。

于 2012-11-13T17:22:02.880 回答
0

在 cellForRowAtIndexPath 中,在调用之前:

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

强制 yourCell imageView.image 为零

imageView.image = nil;

这样你就可以清理旧单元格的内容图像,然后在加载时用正确的图像重绘......

编辑

也许 nil 不起作用...

尝试一个placeHolder图像,一个真正的png文件(带有颜色,用于测试,那么它可能是一个透明文件......)

于 2012-05-10T12:01:10.400 回答
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;
}

然后在你的视图控制器中实现这个方法:

-(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];
        头像.image = ...; // 做你需要做的设置单元格中的图像
    }];
}

您还需要添加UIScrollViewDelegate到您的视图控制器采用的协议列表中。

这里的想法是,只要表格视图在移动,就不必费心加载图像。你的表现会一飞冲天。

于 2012-11-13T17:32:44.640 回答
0

尝试实现您自己的 UItableViewCell 并在 PrepareForReuse 方法中将所有单元格属性设置为 nil。

我还建议你看看这个项目,以便异步加载远程图像: https ://github.com/nicklockwood/AsyncImageView

我在不同的项目中使用它取得了巨大的成功。

于 2012-05-10T12:15:35.830 回答
0

前几天有一个类似的问题,我解决它的方法如下(我没有注意到任何性能下降)。

UITableViewCell *cell;

如果(细胞 == 零){
单元格 = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

// 其余代码

}

所以基本上在 if 中调用 dequeue。

于 2012-05-11T07:20:11.547 回答