从URL加载UITableViewCell的图像(需要异步加载它们)

时间:2014-02-13 09:43:55

标签: ios objective-c uitableview nsurlconnection

我有一个自定义类,它解析XML并获取图像的URL字符串(我存储在数组中)。然后我想检索这些字符串以加载图像并在UITableViewCell中显示每个字符串。这是我的代码:

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

    UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
    labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];

    NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    cell.imageView.image = image;

    return cell;
}

显然,当我向下滚动表格时,应用程序会加载更多图像,并且在加载图像时,用户无法执行任何操作。看起来应用程序冻结了。我想加载的图像不是很大(大约8kb)。也许有一种方法可以加载并将它们存储在后台?我还希望为用户提供更多自由,例如向下滚动并查看带有文本但没有图像的单元格。然后强制应用加载用户当前正在查看的单元格的图像。

有没有办法修改我的代码或任何其他解决方案,以便从URL字符串正确加载图像?

任何建议都将不胜感激,谢谢。

5 个答案:

答案 0 :(得分:3)

尝试异步加载图像,因此主线程不会阻塞。

您的代码如下所示:

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

    UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
    labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];

    NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *image = [UIImage imageWithData:imageData];

        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = image;
        });    
    });

    return cell;
}

答案 1 :(得分:3)

您可以使用SDWebImage框架异步加载图像。

请点击链接: https://github.com/rs/SDWebImage

只需将SDWebImage框架添加到项目中,并设置其他链接器标志'-ObjC'即可使用该框架。

下载链接:https://github.com/rs/SDWebImage/releases

答案 2 :(得分:2)

下载此项目并在单元格的imageview中使用asynimagevei .. link

答案 3 :(得分:2)

将此用于加载imageview的异步方式

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

 UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
 labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];


   //get a dispatch queue
   dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
        NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];

    NSData *image = [[NSData alloc] initWithContentsOfURL:imageURL];

    //this will set the image when loading is finished
    dispatch_async(dispatch_get_main_queue(), ^{
       cell.imageView.image = [UIImage imageWithData:image];
    });
      });

   return cell;
   }

答案 4 :(得分:1)

使用NSOperation和NSOperationQueue.A解决您的问题的完美解决方案。使用以下链接查看它的工作原理。

http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

使用AFNetworking库它还提供了一个UIImageview类别,可以异步下载图像。