带有从 iphone 中的服务器加载的图像的表格视图

Posted

技术标签:

【中文标题】带有从 iphone 中的服务器加载的图像的表格视图【英文标题】:table view with images which are loaded from server in iphone 【发布时间】:2014-12-26 04:39:02 【问题描述】:

您好,我正在开发 ios 应用程序。我的应用程序包含带有图像的表格视图作为表格的一部分。我正在从服务器加载我的图像。它工作正常。但是我的表格视图的问题是,一旦我滚动表格视图,它就会开始闪烁我的图像。这意味着它在一段时间后显示错误的图像一段时间后显示正确的图像。当我滚动时,这种行为会继续。是否需要显式调用任何对象为零或释放一些单元对象或持有一些单元对象。我的表格视图单元格如下所示:

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


static NSString *simpleTableIdentifier = @"MediaContentCell";

MediaContentCell *cell = (MediaContentCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) 
    cell = (MediaContentCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];


VideoDataModel *videoData = [_mediaContentArray objectAtIndex:indexPath.row];

cell.mediaTitle.text = videoData.title;
cell.mediaSubtitle.text = videoData.shortdescription;

NSMutableArray *posters = videoData.poster;

dispatch_queue_t myQueue = dispatch_queue_create("ImageQue",NULL);
dispatch_async(myQueue, ^

    UIImage *image;
    if(!posters)
    
        image = [UIImage imageNamed:@"dummyprog_large1.png"];
    
    else
    
        for(int index = 0 ; index < posters.count; index++)
        
            PosterDataModel *posterData = [posters objectAtIndex:index];
            if([posterData.postertype isEqualToString:POSTER_TYPE_LANDSCAPE])
            
                 image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:posterData.posterurl]]];
                break;
            
        
    

    dispatch_async(dispatch_get_main_queue(), ^
    
        cell.mediaPicture.image = image;
    );
);

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

return cell;

有没有人可以帮助我解决这个问题?需要帮助谢谢。

【问题讨论】:

【参考方案1】:

使用 - SDWebImage

     [cell.imageView sd_cancelCurrentImageLoad];
     [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                       placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

我正在使用这个框架,它对我来说工作得很好。

【讨论】:

这个框架是平台自己提供的还是要外接? 我们必须将它包含在外部。 这个库项目还是只是框架。意味着我无法包含它。怎么做?我是android背景的家伙,对IOS有点新 它的第三方框架。您需要添加到您的项目中。 check this answer 我试图包含这个库项目,但它不适合我。该项目中没有 .framework 或 .a 文件。然后我只是在我的项目中复制了 sdwebimage 文件夹并尝试使用它,但它仍然无法正常工作。你能帮我解决这个问题吗?【参考方案2】:
cell.imageView.image = [UIImage imageWithData:yourDefaultImgUrl];

   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        NSData *imageData = [NSData dataWithContentsOfURL:yourServerImageUrl];      
        if (imageData)
            dispatch_async(dispatch_get_main_queue(), ^
                 UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath];          
                 if (updateCell)
                updateCell.imageView.image = [UIImage imageWithData:imageData];
            );
        
    );

它可以帮助你:)

【讨论】:

【参考方案3】:

导致你的问题是重用机制

比如说,如果你的表格视图有 1000 个单元格要显示,并且一次在屏幕上可见 5 个单元格,iOS 只会在内存中创建 6 个 UITableViewCell 对象。

在你的代码中,图片会从网络异步加载,然后设置为索引路径下属于cell的[mediaPicture],但是当你滚动table view时,由于重用机制,[mediaPicture] cell.mediaPicture] 可能不再与索引路径正确关联,并且下载的图像将被错误设置。

你可以看看这个关于重用机制的问题:

UITableViewCell - Understanding "reuseable"

而 Amol 的回答正是您的案例的解决方案。

【讨论】:

我也使用了相同的 dispatch_asyc。唯一的区别是 dispatch_queue 类型。这就是区别吗?我正在使用 dispatch_queue_t myQueue = dispatch_queue_create("ImageQue",NULL); 和 Amol 建议 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)。它会有所作为吗?谢谢你的帮助。愿意得到更深层次的答案。谢谢。 抱歉回复晚了,不是队列类型导致您的问题,而是因为您在分配下载的图像之前没有检查正确的单元格,这正是 Amol 的代码在此块中所做的: UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath]; if (updateCell)...

以上是关于带有从 iphone 中的服务器加载的图像的表格视图的主要内容,如果未能解决你的问题,请参考以下文章

应用程序的 Documents 文件夹中的图像需要延迟表图像加载

如何在 iPhone 应用程序的 UITableCell 中的背景中加载图像

需要在app的Documents文件夹中为图像加载延迟表图像

如何在 iphone 的 UIImageView 上从远程服务器加载图像?

如何在iphone的tableview中添加按钮控件

Button 中的图像不更新 (iPhone)