使用块在表中加载图像-dispatch_async返回值 [英] loading images in table using blocks - dispatch_async return value

查看:167
本文介绍了使用块在表中加载图像-dispatch_async返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在SO和网络上四处浏览,但没有找到具体答案.

I have looked around on SO and the web and have not found a specific answer.

很简单,我有一个表格,用于从Flickr加载图像信息.我想在每个单元格的左侧显示图像的缩略图.

Quite simply, I have a table loading images info from Flickr. I want to display a thumbnail of the image on the left side of each cell.

为了做到这一点而又不阻塞主(UI)线程,我使用了块:

In order to do this without blocking the main (UI) thread, I am using blocks:

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

  //getting the selected row image 
  NSDictionary* currentImageDictionary=[self.topfifty objectAtIndex:indexPath.row];//topFifty is an array of image dictionaries


  //creating the download queue 
  dispatch_queue_t downloadQueue=dispatch_queue_create("thumbnailImage", NULL);

  dispatch_async(downloadQueue, ^{

    UIImage *downloadedThumbImage=[self getImage:currentImageDictionary] ;

    //Need to go back to the main thread since this is UI related
    dispatch_async(dispatch_get_main_queue(), ^{

        cell.imageView.image = downloadedThumbImage ;

    });

  });

  dispatch_release(downloadQueue);

  return cell;

}

现在这行不通了.因为返回单元很可能会在执行块之前发生.但是同时,我不能返回主队列块中的单元,因为该块不接受返回参数.

Now this is not going to work. Because returning the cell will likely happens before executing the block. But at the same time, I cannot return the cell within the main queue block because the block does not accept a return argument.

我想避免创建UITableViewCell子类.

I want to avoid creating a UITableViewCell subclass.

有使用积木的简单答案吗?

Any simple answer using blocks?

谢谢 九巴

推荐答案

执行cell.imageView.image = downloadedThumbImage;的问题在于,此单元格现在可以重用并用于另一行.

The problem with doing cell.imageView.image = downloadedThumbImage; is that this cell may now be reused and used for another row.

相反,您需要更新特定indexPath中的当前单元格(indexPath将相同)

Instead you need to update the current cell in the specific indexPath (the indexPath will be the same)

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = image;  

有时候,我要做的就是更新模型,然后在特定的indexPath处重新加载单元格:

Or sometimes what I do is to update the model and then reload the cell at the specific indexPath:

myModel.image = downloadedThumbImage;
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                                      withRowAnimation:UITableViewRowAnimationNone];  


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

  //getting the selected row image 
  NSDictionary* currentImageDictionary=[self.topfifty objectAtIndex:indexPath.row];//topFifty is an array of image dictionaries

  UIImage *currentImage = [currentImageDictionary objectForKey:@"image"];

  if (currentImage) { 
      // we already fetched the image, so we just set it to the cell's image view
      cell.imageView.image = currentImage;
  }
  else {
      // we don't have the image, so we need to fetch it from the server  

      // In the meantime, we can set some place holder image
      UIImage *palceholderImage = [UIImage imageNamed:@"placeholder.png"];
      cell.imageView.image = palceholderImage;

      // set the placeholder as the current image to your model, so you won't 
      // download the image multiple times (can happen if you reload this cell while 
      // download is in progress)
      [currentImageDictionary setObject:palceholderImage forKey:@"image"];

      // then download the image
      // creating the download queue 
      dispatch_queue_t downloadQueue=dispatch_queue_create("thumbnailImage", NULL);

      dispatch_async(downloadQueue, ^{
         UIImage *downloadedThumbImage=[self getImage:currentImageDictionary] ;

         //Need to go back to the main thread since this is UI related
         dispatch_async(dispatch_get_main_queue(), ^{
                // store the downloaded image in your model
                [currentImageDictionary setObject:image forKey:@"image"];

                // update UI
                UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                cell.imageView.image = image;    
         });
      });
      dispatch_release(downloadQueue);
  }

  return cell;
}

这篇关于使用块在表中加载图像-dispatch_async返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆